なつねこメモ

主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ 書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。

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
}