可观察的集合属性已更改为集合中的项目
我有一个ObservableCollection
。 我已将它绑定到ListBox控件,我已将SortDescriptions
到ListBox上的Items集合中,以使列表按我的方式排序。
当在子元素上更改任何属性时,我想在任何时候使用列表。
我的所有子元素都实现了INotifyPropertyChanged
。
蛮力:
- 将处理程序附加到每个子项的每个PropertyChanged事件
- 从CollectionViewSource中获取ListCollectionView
- 呼叫刷新。
编辑:
1,2的代码将存在于您的代码隐藏中。
对于#1,您可以执行以下操作:
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** .... } }
对于#2,在CollectionChanged处理程序中,您可以执行以下操作:
private void _SomeItem_PropertyChanged(object sender, PropertyChangedEventArgs e) { ListCollectionView lcv = (ListCollectionView)(CollectionViewSource.GetDefaultView(theListBox.ItemsSource)); lcv.Refresh(); }
EDIT2:但是,在这种情况下,我强烈建议您也检查ListCollectionView.NeedsRefresh并仅在设置时刷新。 如果您的属性已更改且不影响排序,则没有理由重新排序。
这很有效。 每当集合发生变化时,它会重新对集合进行排序。 可能以更有效的方式实现,但这是它的要点。
public partial class TestWindow : Window { ObservableCollection
oc; public TestWindow() { InitializeComponent(); // Fill in the OC for testing oc = new ObservableCollection (); foreach( char c in "abcdefghieeddjko" ) { oc.Add( new TestClass( c.ToString(), c.ToString(), c.GetHashCode() ) ); } lstbox.ItemsSource = oc; // Set up the sorting (this is how you did it.. doesn't work) 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 ( ( x ) => ( xC ) ); // Rest converst IEnumerable back to OC and assigns it ObservableCollection temp = new ObservableCollection (); 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 } public partial class TestWindow : Window { ObservableCollection
oc; public TestWindow() { InitializeComponent(); // Fill in the OC for testing oc = new ObservableCollection (); foreach( char c in "abcdefghieeddjko" ) { oc.Add( new TestClass( c.ToString(), c.ToString(), c.GetHashCode() ) ); } lstbox.ItemsSource = oc; // Set up the sorting (this is how you did it.. doesn't work) 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 ( ( x ) => ( xC ) ); // Rest converst IEnumerable back to OC and assigns it ObservableCollection temp = new ObservableCollection (); 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:
上述就是C#学习教程:可观察的集合属性已更改为集合中的项目分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
窗口> 列表框>
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1040537.html