我有一个名为MyItem的类,该类具有ID属性以及三个随机数属性。我有一个名为MyItemControl的UserControl,旨在显示MyItem的ID,三个随机数以及这三个随机数的总和。我在ListBox中显示MyItems的集合,并且我有一个contentcontrol,它通过MyItemControl UserControl显示有关ListBox所选MyItem的更多详细信息。
但是,我遇到一个问题,当选择MyItem时,contentcontrol仅更新ID和随机数,而不更新总和。我的猜测是因为Sum属性是在将MyItem绑定到MyItemControl之前计算的。我尝试过在设置MyItem属性时更改属性,但这似乎也不起作用。
在xaml中绑定MyItem属性后,如何更新Sum属性?
MyItem类:
public class MyItem
{
private static Random random = new Random();
public MyItem(string ID)
{
this.ID = ID;
Num1 = random.Next();
Num2 = random.Next();
Num3 = random.Next();
}
public string ID { get; private set; }
public int Num1 { get; private set; }
public int Num2 { get; private set; }
public int Num3 { get; private set; }
public override string ToString()
{
return ID;
}
}
MyItemControl xaml:
<UserControl x:Name="userControl" x:Class="testApp2.MyItemControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:testApp2"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel Margin="0">
<StackPanel Margin="0" Orientation="Horizontal">
<Label Content="ID:" Margin="0" HorizontalAlignment="Left"/>
<Label Content="{Binding MyItem.ID, ElementName=userControl, Mode=OneWay}" Margin="0" HorizontalAlignment="Left"/>
</StackPanel>
<StackPanel Margin="0" Orientation="Horizontal">
<Label Content="Num1:" Margin="0" HorizontalAlignment="Left"/>
<Label Content="{Binding MyItem.Num1, ElementName=userControl, Mode=OneWay}" Margin="0" HorizontalAlignment="Left"/>
</StackPanel>
<StackPanel Margin="0" Orientation="Horizontal">
<Label Content="Num2:" Margin="0" HorizontalAlignment="Left"/>
<Label Content="{Binding MyItem.Num2, ElementName=userControl, Mode=OneWay}" Margin="0" HorizontalAlignment="Left"/>
</StackPanel>
<StackPanel Margin="0" Orientation="Horizontal">
<Label Content="Num3:" Margin="0" HorizontalAlignment="Left"/>
<Label Content="{Binding MyItem.Num3, ElementName=userControl, Mode=OneWay}" Margin="0" HorizontalAlignment="Left"/>
</StackPanel>
<StackPanel Margin="0" Orientation="Horizontal">
<Label Content="Sum:" Margin="0" HorizontalAlignment="Left"/>
<Label Content="{Binding Sum, ElementName=userControl, Mode=OneWay}" Margin="0" HorizontalAlignment="Left"/>
</StackPanel>
</StackPanel>
</UserControl>
MyItemControl的代码隐藏:
public partial class MyItemControl : UserControl, INotifyPropertyChanged
{
public MyItemControl()
{
InitializeComponent();
}
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string property)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
public MyItem MyItem
{
get { return (MyItem)GetValue(MyItemProperty); }
set
{
SetValue(MyItemProperty, value);
RaisePropertyChanged("MyItem");
RaisePropertyChanged("Sum");
}
}
public static readonly DependencyProperty MyItemProperty =
DependencyProperty.Register("MyItem", typeof(MyItem), typeof(MyItemControl), new PropertyMetadata(null));
public int Sum => MyItem != null ? MyItem.Num1 + MyItem.Num2 + MyItem.Num3 : 0;
}
MainWindow xaml:
<Window x:Name="window" x:Class="testApp2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:testApp2"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListBox Margin="5" SelectionChanged="ItemSelectionChanged" ItemsSource="{Binding MyItems, ElementName=window}"/>
<ContentControl Content="{Binding Selection, ElementName=window, Mode=OneWay}" Grid.Column="1" Margin="5">
<ContentControl.ContentTemplate>
<DataTemplate DataType="{x:Type local:MyItem}">
<local:MyItemControl MyItem="{Binding}"/>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
</Grid>
</Window>
MainWindow背后的代码:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
MyItems = new ObservableCollection<MyItem>
{
new MyItem("Boop"),
new MyItem("Bop"),
new MyItem("Beep")
};
InitializeComponent();
}
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string property)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
public ObservableCollection<MyItem> MyItems { get; private set; }
private MyItem selection = null;
public MyItem Selection
{
get { return selection; }
set
{
selection = value;
RaisePropertyChanged("Selection");
}
}
private void ItemSelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox listbox = (ListBox)sender;
if (listbox.SelectedIndex > -1)
{
Selection = (MyItem)listbox.SelectedItem;
}
}
}
答案 0 :(得分:0)
来自Clemens的建议。我删除了INotifyPropertyChanged接口,并将PropertyChangedCallback与MyItem属性一起使用,该属性重新计算了Sum属性。这似乎工作正常。
更新的MyItemControl:
public partial class MyItemControl : UserControl
{
public MyItemControl()
{
InitializeComponent();
Sum = MyItem != null ? MyItem.Num1 + MyItem.Num2 + MyItem.Num3 : 0;
}
public MyItem MyItem
{
get { return (MyItem)GetValue(MyItemProperty); }
set { SetValue(MyItemProperty, value); }
}
public static readonly DependencyProperty MyItemProperty =
DependencyProperty.Register("MyItem", typeof(MyItem), typeof(MyItemControl), new PropertyMetadata(null, MyItemPropertyChanged));
private static void MyItemPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
MyItemControl sender = (MyItemControl)obj;
sender.Sum = sender.MyItem.Num1 + sender.MyItem.Num2 + sender.MyItem.Num3;
Console.WriteLine("Update sum");
}
public int Sum
{
get { return (int)GetValue(SumProperty); }
set { SetValue(SumProperty, value); }
}
private static readonly DependencyProperty SumProperty =
DependencyProperty.Register("Sum", typeof(int), typeof(MyItemControl), new PropertyMetadata(0));
}