В WinRT коллекция, реализующая INotifyCollectionChanged без обновления ItemsControl.

Я пишу свой собственный класс коллекции, который также реализует INotifyCollectionChanged. Я использую его в приложении магазина Windows 8 (winRT). Я написал модульный тест, который доказывает, что изменение содержимого списка вызывает все правильные события с теми же событиями, что и «нормальная» наблюдаемая коллекция. Тем не менее, когда я привязываю свойство ItemsSource ItemsControl (я пробовал GridView, ListView и даже простой ванильный ItemsControl) к коллекции, это не влияет на пользовательский интерфейс при изменении коллекции.

Должен ли базовый тип коллекции быть ObservableCollection, чтобы он работал, или можно написать свой собственный класс коллекции?

спасибо


person Kobi Hari    schedule 29.01.2013    source источник
comment
comment
Я заметил интерфейс IObservableVector, но оказалось, что ObservableCollection‹T› его не реализует (или я ошибаюсь). Является ли теперь единственным наблюдаемым интерфейсом коллекции, который необходимо реализовать?   -  person Kobi Hari    schedule 29.01.2013
comment
Возможно, ObservableCollection молча проецируется на IObservableVector...   -  person Filip Skakun    schedule 29.01.2013


Ответы (1)


Вы можете использовать ICollectionView который также имеет некоторые расширенные функции для фильтрации. Если вам нужен готовый класс, ознакомьтесь с . один доступен в Code Project.

В частности, я заметил, что пользовательский интерфейс подписывается на VectorChanged событие, поэтому вам следует реализовать только IObservableCollection, упомянутое ранее в комментариях.

Событие VectorChanged использует интерфейс типа IVectorChangedEventArgs, и при осмотре я не нашел конкретных классов. Хотя создать его не сложно. Вот тот, который можно создать аналогично тому, как вы создаете экземпляр NotifyPropertyChangedEventArgs. Он закрытый, поскольку используется только в классе коллекции.

private sealed class VectorChangedEventArgs : IVectorChangedEventArgs
{
    public VectorChangedEventArgs(NotifyCollectionChangedAction action, object item, int index)
    {
        switch (action)
        {
            case NotifyCollectionChangedAction.Add:
            CollectionChange = CollectionChange.ItemInserted;
            break;
            case NotifyCollectionChangedAction.Remove:
            CollectionChange = CollectionChange.ItemRemoved;
            break;
            case NotifyCollectionChangedAction.Move:
            case NotifyCollectionChangedAction.Replace:
            CollectionChange = CollectionChange.ItemChanged;
            break;
            case NotifyCollectionChangedAction.Reset:
            CollectionChange = CollectionChange.Reset;
            break;
            default:
            throw new ArgumentOutOfRangeException("action");
        }
        Index = (uint)index;
        Item = item;
    }

    /// <summary>
    /// Gets the affected item.
    /// </summary>
    public object Item { get; private set; }

    /// <summary>
    /// Gets the type of change that occurred in the vector.
    /// </summary>
    public CollectionChange CollectionChange { get; private set; }

    /// <summary>
    /// Gets the position where the change occurred in the vector.
    /// </summary>
    public uint Index { get; private set; }
}
person Patrick    schedule 06.05.2013