问题描述
我这个链接
ObservableCollection当它改变项(即使有INotifyPropertyChanged的)
一些技巧来通知的ObservableCollection项目已改变。在这个环节中TrulyObservableCollection似乎正是我要找的。
some techniques to notify a Observablecollection that an item has changed. the TrulyObservableCollection in this link seems to be what i'm looking for.
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#code:
But when I try to use it, I don't get notifications on the collection. I'm not sure how to correctly implement this in my C# Code:
XAML:
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding MyItemsSource, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<DataGrid.Columns>
<DataGridCheckBoxColumn Binding="{Binding MyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataGrid.Columns>
</DataGrid>
视图模型:
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复选框假,真,假作为财产的初始化。
但是,当我改变ckeckbox的一个状态,该程序通过item_PropertyChanged但从未在MyItemsSource物业code。
When i run the program, i have the 3 checkbox to false, true, false as in the property initialisation.but when i change the state of one of the ckeckbox, the program go through item_PropertyChanged but never in MyItemsSource Property code.
推荐答案
您已经评价为 // code到trig的有关项目变更现货...
只会触发时集合对象得到改变,当它被设置为一个新的对象,或设置为null,如
The spot you have commented as // Code to trig on item change...
will only trigger when the collection object gets changed, such as when it gets set to a new object, or set to null.
使用您的当前实现TrulyObservableCollection的,办理产权变更您的收藏活动,注册的东西 MyItemsSource CollectionChanged
事件C $ C>
With your current implementation of TrulyObservableCollection, to handle the property changed events of your collection, register something to the CollectionChanged
event of 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
事件,说整个集合已被重置,任何时候一个属性更改。当然它会让用户界面随时更新在收集变更的项目,但我看到,是对性能不好,它似乎并不有一种方法来确定哪些属性改变,这是信息的关键件之一我通常需要做的的PropertyChanged
东西的时候。
Personally I really don't like this implementation. You are raising a CollectionChanged
event that says the entire collection has been reset, anytime a property changes. Sure it'll make the UI update anytime an item in the collection changes, but I see that being bad on performance, and it doesn't seem to have a way to identify what property changed, which is one of the key pieces of information I usually need when doing something on PropertyChanged
.
使用普通的的ObservableCollection
,只是挂钩的的PropertyChanged
事件给它 CollectionChanged 。提供您的UI正确绑定到项目的ObservableCollection
,你不应该需要告诉UI更新时在收集变化的项目的属性。
I prefer using a regular ObservableCollection
and just hooking up the PropertyChanged
events to it's items on CollectionChanged
. Providing your UI is bound correctly to the items in the ObservableCollection
, you shouldn't need to tell the UI to update when a property on an item in the collection changes.
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当项目发生变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!