Обновление CollectionViewSource, когда ObservableCollection меняет WP7 - PullRequest
4 голосов
/ 15 апреля 2011

У меня есть ObservableCollection для моего базового списка предметов.У меня 2 CollectionViewSource, которые являются разными фильтрами данных.Я хочу, чтобы любые изменения отражались в CollectionViewSource.

. В моем конструкторе модели представления я устанавливаю предикаты фильтра.Затем я получаю данные и добавляю их к ObservableCollection.Я подписан на событие CollectionChanged и обновляю там CVS.

Хотя я вижу некоторые действительно странные вещи с этим.Либо элементы не будут отображаться в моем ListBox, связанном с CVS, либо появятся дубликаты.Если я позвоню Refresh на CVS вне события CollectionChanged после изменения ObservableCollection, все будет работать нормально.Мне бы очень хотелось иметь возможность просто обновлять, когда коллекция меняется, и не беспокоиться о необходимости вызывать обновление каждый раз, когда что-то делается, что меняет это.

public MyViewModel()
{
    oc.CollectionChanged += OcCollectionChanged;

    cvs1.Source = oc;
    cvs1.View.Filter = new Predicate<object>( ... );

    cvs2.Source = oc;
    cvs2.View.Filter = new Predicate<object>( ... );

    foreach( var data in myData )
    {
        oc.Add( data );
    }
}

private void OcCollectionChanged( object sender, NotifyCollectionChangedEventArgs e )
{
    cvs1.View.Refresh();
    cvs2.View.Refresh();
}

Ответы [ 3 ]

3 голосов
/ 15 апреля 2011

CollectionViewSource не реализует INotifyPropertyChanged, поэтому для внесения любых изменений базовых данных в пользовательский интерфейс необходимо вызвать Refresh в представлении, как вы уже это делаете.CollectionViewSource также не зависит от источника данных, поэтому тот факт, что источником является ObservableCollection, который вызывает уведомление об изменении свойства, несущественен, поскольку CollectionViewSource не прослушивает.

Я думаю, что у вас есть решениеОбновление представлений вручную, когда изменения в коллекции - это лучшее, что вы получите, не переосмысливая структуры данных.

2 голосов
/ 02 декабря 2011

Я знаю, что это немного устарело, но я использую модифицированный класс ObservableCollection, который специально преодолевает ограничение, упомянутое выше (событие CollectionChangedEvent запускается несколько раз), найденное здесь . (ObservableCollectionEx - блокирует CollectionChangedEvent, пока все не будут добавлены путем добавления метода AddRange)

Я использую его уже около 2 лет, и он отлично работает при больших изменениях коллекции.

Обновление
Похоже, что ссылка не работает, поэтому вот код:

public class ObservableCollectionEx<T> : ObservableCollection<T>
{
    public ObservableCollectionEx()
        : base()
    {
        _suspendCollectionChangeNotification = false;
    }


    bool _suspendCollectionChangeNotification;

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if(!_suspendCollectionChangeNotification)
        {
            base.OnCollectionChanged(e);
        }
    }

    public void SuspendCollectionChangeNotification()
    {
        _suspendCollectionChangeNotification = true;
    }

    public void ResumeCollectionChangeNotification()
    {
        _suspendCollectionChangeNotification = false;
    }


    public void AddRange(IEnumerable<T> items)
    {
        this.SuspendCollectionChangeNotification();
        int index = base.Count;
        try
        {
            foreach(var i in items)
            {
                base.InsertItem(base.Count, i);
            }
        }
        finally
        {
            this.ResumeCollectionChangeNotification();
            var arg = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
            this.OnCollectionChanged(arg);
        }
    }

}
0 голосов
/ 15 апреля 2011

Проблема в том, что ObservableCollection имеет свои ограничения.Рассмотрим тот цикл, который есть в вашем коде, как может он вызывать метод Add?Сколько раз будет происходить измененное событие и как часто будут вызываться методы обновления?Не слишком удивительно, что этот код оказывается в самом разгаре, когда так много изменений происходит в быстрой последовательности.

ObservableCollection великолепен, когда он изначально загружен, тогда отслеживается его событие изменения, и небольшие относительно редкие изменениясделано с этого момента.Для крупномасштабных изменений, вероятно, лучше загрузить совершенно новый экземпляр, а затем назначить этот новый экземпляр свойству.

Пусть установщик свойств переназначит свойства Source для объектов CollectionViewSource.Если вы все еще хотите наблюдать коллекцию, вы можете отсоединить и прикрепить ваши обработчики событий в установщике.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...