项目更改时通知ObservableCollection
我在此链接上找到了
ObservableCollection不会注意到其中的Item更改的时间(即使使用INotifyPropertyChanged)
通知Observablecollection某项已更改的某些技术。该链接中的TrulyObservableCollection似乎是我正在寻找的东西。
public class TrulyObservableCollection<T> : ObservableCollection<T>where T : INotifyPropertyChanged
{
public TrulyObservableCollection()
: base()
{
CollectionChanged += new NotifyCollectionChangedEventHandler(TrulyObservableCollection_CollectionChanged);
}
void TrulyObservableCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (Object item in e.NewItems)
{
(item as INotifyPropertyChanged).PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged);
}
}
if (e.OldItems != null)
{
foreach (Object item in e.OldItems)
{
(item as INotifyPropertyChanged).PropertyChanged -= new PropertyChangedEventHandler(item_PropertyChanged);
}
}
}
void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
NotifyCollectionChangedEventArgs a = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
OnCollectionChanged(a);
}
}
但是,当我尝试使用它时,我没有收到关于集合的通知。我不确定如何在我的C#代码中正确实现这一点:
XAML:
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding MyItemsSource, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> <DataGrid.Columns>
<DataGridCheckBoxColumn Binding="{Binding MyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataGrid.Columns>
</DataGrid>
ViewModel:
public class MyViewModel : ViewModelBase{
private TrulyObservableCollection<MyType> myItemsSource;
public TrulyObservableCollection<MyType> MyItemsSource
{
get { return myItemsSource; }
set
{
myItemsSource = value;
// Code to trig on item change...
RaisePropertyChangedEvent("MyItemsSource");
}
}
public MyViewModel()
{
MyItemsSource = new TrulyObservableCollection<MyType>()
{
new MyType() { MyProperty = false },
new MyType() { MyProperty = true },
new MyType() { MyProperty = false }
};
}
}
public class MyType : ViewModelBase
{
private bool myProperty;
public bool MyProperty
{
get { return myProperty; }
set
{
myProperty = value;
RaisePropertyChangedEvent("MyProperty");
}
}
}
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChangedEvent(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName);
PropertyChanged(this, e);
}
}
}
当我运行程序时,与属性初始化一样,我有3个复选框为false,true,false。但是,当我更改ckeckbox之一的状态时,该程序将通过item_PropertyChanged,但永远不会在MyItemsSource属性代码中进行。
回答:
您注释为的位置// Code to trig on item change...
仅在更改集合对象(例如将其设置为新对象或设置为null)时触发。
根据您目前的实现TrulyObservableCollection的,处理您的的属性更改事件,注册一些东西到CollectionChanged
的事件MyItemsSource
public MyViewModel(){
MyItemsSource = new TrulyObservableCollection<MyType>();
MyItemsSource.CollectionChanged += MyItemsSource_CollectionChanged;
MyItemsSource.Add(new MyType() { MyProperty = false });
MyItemsSource.Add(new MyType() { MyProperty = true});
MyItemsSource.Add(new MyType() { MyProperty = false });
}
void MyItemsSource_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// Handle here
}
我个人真的不喜欢这种实现。您正在引发一个CollectionChanged
事件,该事件表明在属性更改时,整个集合已被重置。当然,只要集合中的某个项目发生更改,它就可以使UI随时更新,但是我发现这样做对性能不利,而且似乎没有办法确定更改了哪些属性,这是关键信息之一做某事时我通常需要PropertyChanged
。
我更喜欢使用常规方法,ObservableCollection
而只是将PropertyChanged
事件关联到上的项目CollectionChanged
。如果您的UI已正确绑定到中的项目,则ObservableCollection
当集合中某个项目的属性发生更改时,您无需告诉UI进行更新。
public MyViewModel(){
MyItemsSource = new ObservableCollection<MyType>();
MyItemsSource.CollectionChanged += MyItemsSource_CollectionChanged;
MyItemsSource.Add(new MyType() { MyProperty = false });
MyItemsSource.Add(new MyType() { MyProperty = true});
MyItemsSource.Add(new MyType() { MyProperty = false });
}
void MyItemsSource_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
foreach(MyType item in e.NewItems)
item.PropertyChanged += MyType_PropertyChanged;
if (e.OldItems != null)
foreach(MyType item in e.OldItems)
item.PropertyChanged -= MyType_PropertyChanged;
}
void MyType_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "MyProperty")
DoWork();
}
以上是 项目更改时通知ObservableCollection 的全部内容, 来源链接: utcz.com/qa/410190.html