“你可以为每个属性引发一个事件.在这种情况下,事件的名称必须是PropertyNameChanged(例如,UnitCostChanged).当你更改属性时,你需要触发事件.”
有人可以确认此功能有效吗?我正在尝试并且无法重现这种行为(我想知道这是否有效,然后我可以尝试使用System.Reflection.Emit来创建动态类型)
编辑:我应该澄清这里的重点是实现更改通知而不实现INotifyPropertyChanged,因为这是本书的主张
这是我正在测试的POCO:
public class Employee { private string _FirstName; public string FirstName { get { return _FirstName; } set { if (_FirstName != value) { _FirstName = value; if (FirstNameChanged != null) { FirstNameChanged(this,new PropertyChangedEventArgs("FirstName")); } } } } }
我将它绑定到DataGrid并在后台有一个计时器每隔几秒随机更新FirstName属性,但DataGrid永远不会触发
<DataGrid x:Name="dgEmployees" ItemsSource="{Binding ElementName=mainWindow,Path=MyEmployees}"> <DataGrid.Columns> <DataGridTextColumn Header="FirstName" Binding="{Binding Path=FirstName}" /> </DataGrid.Columns> </DataGrid>
FirstNameChanged事件始终为null(我认为绑定引擎可能会在根据命名约定检测到它时自动订阅它). MyEmployees只是一个ObservableCollection
有人可以确认作者提到的这个功能是否确实有效,如果我犯了错误?
编辑:为了任何认为我错误解释文本的人的利益:
您可以使用,使Product类中的每个属性成为依赖项属性
您在第4章中学到的语法.(在这种情况下,您的类必须派生自
DependencyObject.)虽然这种方法可以让WPF为你完成工作
(这很好),它在具有视觉效果的元素类中最有意义
在窗口中出现.对于数据类来说,这不是最自然的方法
产品.
您可以为每个房产举办活动.在这种情况下,事件必须具有
name PropertyNameChanged(例如,UnitCostChanged).这取决于你
在更改属性时触发事件.
您可以实现System.ComponentModel.INotifyPropertyChanged
interface,需要一个名为PropertyChanged的事件.那你必须
只要属性发生变化,就会引发PropertyChanged事件,并指出哪一个
通过将属性名称作为字符串提供,已更改属性.它仍然是
您在属性更改时引发此事件,但您不需要定义
每个房产都有单独的活动.“
解决方法
如果您在属性值发生更改时从POCO更改了一个名为{Propertyname}的事件,WPF绑定系统将选择该项,并更新相关绑定.
看一下这个小程序进行演示 – 这是我能想到的最简单的事情,但我想它也适用于你的情况.
XAML:
<StackPanel> <TextBlock Text="{Binding Name}" /> <Button Content="Change name" Click="changeNameClick" /> </StackPanel>
代码隐藏:
public partial class Window1 : Window { private SimpleObject so = new SimpleObject(); public Window1() { InitializeComponent(); this.so = new SimpleObject(); so.Name = "Initial value"; this.DataContext = so; var t = new DispatcherTimer( TimeSpan.FromSeconds(1),DispatcherPriority.Normal,(s,e) => { this.so.Name = "Name changed at: " + DateTime.Now.ToString(); },Dispatcher); } private void changeNameClick(object sender,RoutedEventArgs e) { this.so.Name = "New value!!"; } } public class SimpleObject { private string mName = null; public string Name { get { return mName; } set { if (mName != value) { mName = value; if (NameChanged != null) NameChanged(this,EventArgs.Empty); } } } public event EventHandler NameChanged; }