wpf集合变更通知

在使用WPF开发应用程序时,经常需要将数据绑定到UI控件中,例如ListView、DataGrid等控件。当使用集合类型作为数据源时,需要确保UI控件能够及时地响应集合的变更,例如增加、删除、修改等操作。为了实现这个功能,需要使用集合变更通知。

集合变更通知是一种机制,用于通知WPF控件集合的变化。当集合中的元素发生变化时,可以通知WPF控件重新绑定数据源,并更新UI界面。WPF中提供了两种集合变更通知接口:INotifyCollectionChanged和ICollectionView。.

1. INotifyCollectionChanged

INotifyCollectionChanged是WPF中的集合变更通知接口,它定义了CollectionChanged事件和一些方法,用于通知集合的变化。

```csharppublic interface INotifyCollectionChanged{    event NotifyCollectionChangedEventHandler CollectionChanged;}

public delegate void NotifyCollectionChangedEventHandler(object sender, NotifyCollectionChangedEventArgs e);```

使用INotifyCollectionChanged接口需要实现CollectionChanged事件。在集合发生变化时,调用CollectionChanged事件,通知WPF控件重新绑定数据源,并更新UI界面。

```csharppublic class PersonCollection : ObservableCollection<Person>{    public PersonCollection()        : base()    {    }

    public PersonCollection(List<Person> list)        : base(list)    {    }

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)    {        base.OnCollectionChanged(e);    }}```

在上面的代码中,定义了一个PersonCollection集合,它继承自ObservableCollection<Person>,实现了INotifyCollectionChanged接口。当集合中的元素发生变化时,调用OnCollectionChanged方法,触发CollectionChanged事件,通知WPF控件更新UI界面。

2. ICollectionView

ICollectionView是WPF中的集合变更通知接口,它提供了对集合进行排序、过滤、分组等操作,并实现了INotifyCollectionChanged接口,用于通知集合的变化。

```csharppublic interface ICollectionView : IEnumerable, INotifyCollectionChanged{    bool CanFilter { get; }    bool CanGroup { get; }    bool CanSort { get; }    bool Contains(object item);    IDisposable DeferRefresh();    bool MoveCurrentTo(object item);    bool MoveCurrentToFirst();    bool MoveCurrentToLast();    bool MoveCurrentToNext();    bool MoveCurrentToPosition(int position);    bool MoveCurrentToPrevious();    void Refresh();    SortDescriptionCollection SortDescriptions { get; }    IEnumerable SourceCollection { get; }    bool IsCurrentAfterLast { get; }    bool IsCurrentBeforeFirst { get; }    object CurrentItem { get; }    int CurrentPosition { get; }    event CurrentChangingEventHandler CurrentChanging;    event EventHandler CurrentChanged;}```

使用ICollectionView接口需要实现CurrentChanging和CurrentChanged事件。在集合中的元素发生变化时,调用CurrentChanged事件,通知WPF控件重新绑定数据源,并更新UI界面。

```csharppublic class PersonViewModel : INotifyPropertyChanged{    private ObservableCollection<Person> _persons;    private ICollectionView _personView;

    public PersonViewModel()    {        _persons = new ObservableCollection<Person>();        _personView = CollectionViewSource.GetDefaultView(_persons);        _personView.CurrentChanged += OnCurrentChanged;    }

    public ICollectionView PersonView    {        get { return _personView; }    }

    private void OnCurrentChanged(object sender, EventArgs e)    {        NotifyPropertyChanged("CurrentPerson");    }

    public Person CurrentPerson    {        get        {            return _personView.CurrentItem as Person;        }    }

    // ...}```

在上面的代码中,定义了一个PersonViewModel视图模型类,实现了INotifyPropertyChanged接口,并使用ICollectionView实现集合变更通知。在PersonViewModel的构造函数中,使用CollectionViewSource.GetDefaultView方法获取ICollectionView对象,并订阅CurrentChanged事件,通知WPF控件更新UI界面。当集合中的元素发生变化时,调用OnCurrentChanged方法,使CurrentPerson属性能够及时更新UI控件。

需要注意的是,无论使用INotifyCollectionChanged还是ICollectionView,集合变更通知机制都需要在WPF控件中正确地绑定数据源,并设置绑定模式为OneWay或TwoWay。只有这样,才能使WPF控件能够及时响应集合的变化,并更新UI界面。