项目更改时通知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

回到顶部