假设,我有对象:
public interface ITest { string Data { get; set; } } public class Test1 : ITest,INotifyPropertyChanged { private string _data; public string Data { get { return _data; } set { if (_data == value) return; _data = value; OnPropertyChanged("Data"); } } protected void OnPropertyChanged(string propertyName) { var h = PropertyChanged; if (null != h) h(this,new PropertyChangedEventArgs(propertyName)); } public event PropertyChangedEventHandler PropertyChanged; }
及其持有人:
private BindingList<ITest> _listTest1; public BindingList<ITest> ListTest1 { get { return _listTest1 ?? (_listTest1 = new BindingList<ITest>() { RaiseListChangedEvents = true }); } }
另外,我订阅了ListChangedEvent
public MainWindow() { InitializeComponent(); ListTest1.ListChanged += new ListChangedEventHandler(ListTest1_ListChanged); } void ListTest1_ListChanged(object sender,ListChangedEventArgs e) { MessageBox.Show("ListChanged1: " + e.ListChangedType); }
和2个测试处理程序:
用于添加对象
private void AddITestHandler(object sender,RoutedEventArgs e) { ListTest1.Add(new Test1 { Data = Guid.NewGuid().ToString() }); }
并改变
private void ChangeITestHandler(object sender,RoutedEventArgs e) { if (ListTest1.Count == 0) return; ListTest1[0].Data = Guid.NewGuid().ToString(); //if (ListTest1[0] is INotifyPropertyChanged) // MessageBox.Show("really pch"); }
ItemAdded发生,但ItemChanged没有.在seeting proprty里面“Data”我发现我的事件PropertyChanged没有订阅者:
protected void OnPropertyChanged(string propertyName) { var h = PropertyChanged; // h is null! why?? if (null != h) h(this,new PropertyChangedEventArgs(propertyName)); } public event PropertyChangedEventHandler PropertyChanged;
深入挖掘我采用反射器并发现BindingList:
protected override void InsertItem(int index,T item) { this.EndNew(this.addNewPos); base.InsertItem(index,item); if (this.raiseItemChangedEvents) { this.HookPropertyChanged(item); } this.FireListChanged(ListChangedType.ItemAdded,index); } private void HookPropertyChanged(T item) { INotifyPropertyChanged changed = item as INotifyPropertyChanged; if (changed != null) // Its seems like null reference! really?? { if (this.propertyChangedEventHandler == null) { this.propertyChangedEventHandler = new PropertyChangedEventHandler(this.Child_PropertyChanged); } changed.PropertyChanged += this.propertyChangedEventHandler; } }
我哪里错了?或者这是已知的bug,我需要找到一些解决方法?
谢谢!
解决方法
的BindingList< T>不检查每个特定项是否实现INotifyPropertyChanged.相反,它会检查一次通用类型参数.所以如果你的BindingList< T>声明如下:
private BindingList<ITest> _listTest1;
然后,ITest应继承自IncotPropertyChanged,以便获取BindingList引发ItemChanged事件.