CollectionView in WPF
wpf的集合controls, 都会有一个内在的viewmodel, 即ICollectionView;来支持sort ,filter, collection view 就是view model
wpf 根据data source 集合自动产生对应的collection view, ListCollectionView(IList ,OberservableCollection),BindingListCollectionView;(BindingListCollectionView 没有像ListCollectionView一样的sort能力,它使用IBindingList的sort定义,具体见:http://www.wpfmentor.com/2008/12/how-to-sort-bindinglist-using.html)
对于IEnumerable数据源,产生一个EnumerableCollectionView,可惜这个类是internal .如果ListBox.ItemSource = Ilist, 自动产生一个ListCollectionView.
用ICollectionView CollectionViewSource.GetDefaultView(object) 可以获得collection view,并且通过这个类在xaml中操作collection view.
在ListCollectionView中,有一个internal list,当用户设置sort,filter时通过这个list产生需要的enumerable在界面上展示;而不用真正修改数据源。(SourceCollection).
对于实现了INotifyPropertyChanged,INotifyCollectionChanged的数据源,如果设置IsSynchronizationCurrentItem=true; 这样就能实现view与collection view 的完全同步,通过操作collection view,也能在view中显示出来。 如CurrentItem,CurrentPosition,都是界面对应的item与position. 比如设置了filter,在原数据源中此数据index=3,在 view中显示index=2,则currentPosition =2.
附custom observable collection 实现:
public class MySampleClass : INotifyPropertyChanged
{ public int MyProperty { get { return _myProperty; } set { if (_myProperty == value) return; _myProperty = value; OnPropertyChanged("MyProperty"); } } public interface ICustomObservableCollection<T> : ICollection<T>, INotifyCollectionChanged, INotifyPropertyChanged
{ }#region Implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) { if (PropertyChanged != null) { PropertyChanged(this, e); } } private void OnPropertyChanged(string propertyName) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } #endregion#region Implementation of INotifyCollectionChanged
public event NotifyCollectionChangedEventHandler CollectionChanged; protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { if (CollectionChanged != null) { using (BlockReentrancy()) { CollectionChanged(this, e); } } } private void OnCollectionChanged(NotifyCollectionChangedAction action, object item) OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item)); } private void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index) { OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index)); } private void OnCollectionReset() OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } .#endregion
浙公网安备 33010602011771号