Observable Collection Property Changed on Item in the Collection 在集合中的项目上,可观察集合属性已更改
ObservableCollection
以下是修改后的代码:
public partial class TestWindow : Window { ObservableCollection<TestClass> oc; public TestWindow() { InitializeComponent(); // Fill in the OC for testing oc = new ObservableCollection<TestClass>(); foreach( char c in "abcdefghieeddjko" ) { oc.Add( new TestClass( c.ToString(), c.ToString(), c.GetHashCode() ) ); } lstbox.ItemsSource = oc; // Set up the sorting lstbox.Items.SortDescriptions.Add( new SortDescription("A", ListSortDirection.Ascending) ); // This is how we're going to do it oc.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler( oc_Sort ); } void oc_Sort( object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e ) { // This sorts the oc and returns IEnumerable var items = oc.OrderBy<TestClass, int>( ( x ) => ( x.C ) ); // Rest convert IEnumerable back to OC and assigns it ObservableCollection<TestClass> temp = new ObservableCollection<TestClass>(); foreach( var item in items ) { temp.Add( item ); } oc = temp; } private void Button_Click( object sender, RoutedEventArgs e ) { string a = "grrrr"; string b = "ddddd"; int c = 383857; oc.Add( new TestClass( a, b, c ) ); } } public class TestClass : INotifyPropertyChanged { private string a; private string b; private int c; public TestClass( string f, string g, int i ) { a = f; b = g; c = i; } public string A { get { return a; } set { a = value; OnPropertyChanged( "A" ); } } public string B { get { return b; } set { b = value; OnPropertyChanged( "B" ); } } public int C { get { return c; } set { c = value; OnPropertyChanged( "C" ); } } #region onpropertychanged public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged( string propertyName ) { if( this.PropertyChanged != null ) { PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) ); } } #endregion }XAML:
<Window x:Class="ServiceManager.TestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TestWindow" Height="500" Width="500">
<DockPanel>
<ListBox ItemsSource="{Binding}" x:Name="lstbox">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding Path=A}"/>
<Label Content="{Binding Path=B}"/>
<Label Content="{Binding Path=C}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Click="Button_Click" Content="Click" />
</DockPanel>
</Window>
问题的原因是ObservableCollection
无法监听其元素的PropertyChanged事件,解决方法是在TestClass类中实现INotifyPropertyChanged接口,并在属性的setter方法中调用OnPropertyChanged方法来通知属性更改。另外,需要在oc_Sort方法中重新创建一个新的ObservableCollection对象,并将排序后的元素重新添加到新的集合中。这样在集合元素属性更改时,集合会重新排序。
Observable Collection Property Changed on Item in the Collection
当在集合中的项上发生Observable Collection属性更改时,可能会出现问题。下面是解决该问题的原因和方法。
问题原因:
Observable Collection是一个特殊的集合类型,当其中的项发生更改时,它会自动通知订阅者。然而,当集合中的项的属性发生更改时,Observable Collection本身并不会触发属性更改事件。这意味着,如果我们希望在集合中的项的属性更改时接收通知,我们需要手动处理。
解决方法:
以下是一种解决方法,通过在每个子项上附加PropertyChanged事件处理程序来实现:
1. 为每个子项的PropertyChanged事件附加处理程序。
2. 从CollectionViewSource中获取ListCollectionView。
3. 调用Refresh方法。
代码示例:
private void Source_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { switch (e.Action) { case NotifyCollectionChangedAction.Add: foreach( SomeItem item in e.NewItems) { item.PropertyChanged += new PropertyChangedEventHandler(_SomeItem_PropertyChanged); } break; // HANDLE OTHER CASES HERE } } private void _SomeItem_PropertyChanged(object sender, PropertyChangedEventArgs e) { ListCollectionView lcv = (ListCollectionView)(CollectionViewSource.GetDefaultView(theListBox.ItemsSource)); lcv.Refresh(); }
在此示例中,Source_CollectionChanged方法用于处理Observable Collection的CollectionChanged事件。在该方法中,我们检查了事件的类型,如果是添加操作,我们遍历新添加的项并为每个项的PropertyChanged事件附加处理程序。
_SomeItem_PropertyChanged方法是PropertyChanged事件的处理程序。在该方法中,我们获取ListCollectionView并调用Refresh方法,以便刷新视图。
在解决此问题时,可以选择仅在ListCollectionView.NeedsRefresh设置为true时刷新视图,以避免不必要的排序操作。
这些代码可以放在窗口的代码后台中(Window.Xaml.Cs)。
以上就是解决Observable Collection Property Changed on Item in the Collection问题的原因和方法。