【发布时间】:2012-01-19 09:42:06
【问题描述】:
我在这个链接上找到了
ObservableCollection not noticing when Item in it changes (even with INotifyPropertyChanged)
一些技术来通知 Observablecollection 项目已更改。此链接中的 TrulyObservableCollection 似乎是我正在寻找的。p>
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>
视图模型:
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,就像在属性初始化中一样。 但是当我更改其中一个复选框的状态时,程序会通过 item_PropertyChanged 但从未在 MyItemsSource 属性代码中。
【问题讨论】:
-
您是否尝试过在调试器中跟踪 RaisePropertyChangedEvent 方法?换句话说,控件是否进入 if 块?
-
ObservableCollection不应该在集合中某个项目的属性更改时引发CollectionChanged。因为收藏没有改变。我无法弄清楚您实际上想要做什么,但我认为您可能会从查看 ContinuousLINQ 中受益——clinq.codeplex.com。 -
我使用了代码。问题是您取消订阅所有旧项目的属性更改事件。我评论了那部分,一切都很顺利。
-
而不是 TrulyObservableCollection 只需使用 System.ComponentModel.BindingList<T>
标签: c# wpf collections observablecollection inotifypropertychanged