読者です 読者をやめる 読者になる 読者になる

みかづきメモ

学習したことのメモとか、日記とか、備忘録。

UWP で ItemsControl.Items の変更を検知したい

WPF だと、 ItemsControl.ItemsINotifyCollectionChanged を実装しているので、
いつもどおり検知できるのですが、 UWP だとなくてちょっと困ったのでメモ。


INotifyCollectionChanged の代わりに、 IObservableVector を実装しているので、
そちらを使うことで検知可能です。

IObservableVector<T> interface - Windows app development

実装例はこんな感じ。

internal class ListBoxEmptyBehavior : Behavior<ItemsControl>
{
    private bool _isAttached;

    private void AssociatedObjectOnDataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
    {
        if (AssociatedObject.Items == null)
            return;
        if (!_isAttached)
        {
            _isAttached = true;
            AssociatedObject.Items.VectorChanged += ItemsOnVectorChanged;
        }
    }

    private void ItemsOnVectorChanged(IObservableVector<object> sender, IVectorChangedEventArgs e)
    {
        switch (e.CollectionChange)
        {
            case CollectionChange.ItemInserted:
                Debug.WriteLine("追加された");
                break;

            case CollectionChange.ItemRemoved:
                Debug.WriteLine("削除された");
                break;

            case CollectionChange.ItemChanged:
                Debug.WriteLine("変更された");
                break;

            case CollectionChange.Reset:
                Debug.WriteLine("リセットされた");
                break;
        }
    }

    #region Overrides of Behavior<ItemsControl>

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.DataContextChanged += AssociatedObjectOnDataContextChanged;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.DataContextChanged -= AssociatedObjectOnDataContextChanged;
        if (AssociatedObject.Items != null && _isAttached)
            AssociatedObject.Items.VectorChanged -= ItemsOnVectorChanged;
    }

    #endregion
}