3

我希望我自己的后代ObservableCollection支持AddRange方法。这是我目前拥有的:

public class ObservableCollectionPlus<T> : ObservableCollection<T>
{
    public void InsertRange(IEnumerable<T> items)
    {
        this.CheckReentrancy();
        foreach (var item in items) Items.Add(item);

        var type = NotifyCollectionChangedAction.Reset;
        var colChanged = new NotifyCollectionChangedEventArgs(type);
        var countChanged = new PropertyChangedEventArgs("Count");

        OnPropertyChanged(countChanged);
        OnCollectionChanged(colChanged);
    }
}

我对这里到底发生了什么以及为什么会引发这些事件知之甚少。这是我在对 google 和 stackoverflow 进行一些研究后组装的一个解决方案。

现在,如果我绑定我的类的一个实例然后说,在通过toLongListSelector动态添加项目之后,绑定的滚动位置被发送到它的顶部。InsertRangeObservableCollectionPlusLongListSelector

如果我以这种标准方式添加项目:foreach (var item in items) collection.Add(item);thenLongListSelector的位置不会移动。但当然,这样我会得到不希望的 DataBinding 通知开销。

显然,我当前的解决方案有问题。我怎样才能实现InsertRange它的行为完全一样foreach (var item in items) collection.Add(item);,但只会触发一次 DataBinding 通知,并且不会对绑定对象的滚动位置做奇怪的事情?

4

4 回答 4

3

可能是因为您发送了NotifyCollectionChangedAction.Reset通知,也许只是NotifyCollectionChangedAction.Add可行,也许:)

public class ObservableRangeCollection<T> : ObservableCollection<T>
{
    public void AddRange(IEnumerable<T> collection)
    {
        foreach (var i in collection)
        {
            Items.Add(i);
        }
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, collection.ToList()));
    }
}
于 2013-01-29T21:16:12.447 回答
2

我最近在一个项目中使用了它...

public class RangeObservableCollection<T> : ObservableCollection<T>
{
    private bool _suppressNotification = false;

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

    public void AddRange(IEnumerable<T> list)
    {
        if (list == null)
            throw new ArgumentNullException("list");

        _suppressNotification = true;

        foreach (T item in list)
        {
            Add(item);
        }
        _suppressNotification = false;
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }
}
于 2013-01-30T08:49:33.370 回答
0

您在使用 DataBinding 时遇到的问题可能与您没有根据源代码在 ObservableCollection 中为索引器(属性名称“Item []”)引发 PropertyChanged 的​​事实有关。

您还可以在 GitHub 上查看James Montemagno的ObservableRangeCollection的一个很好的实现,它继承自ObservableColection并包括AddRangeReplaceRange方法以及 DataBinding 所需的所有 PropertyChaged 和 CollectionChanged 通知。

于 2018-09-05T14:19:09.483 回答
-1

我花了很长时间,问题总是与传递给 NotifyCollectionChangedEventArgs ctor 的参数有关。根据动作的不同,有许多不同的 ctor 采用不同的参数。以下似乎最终对我有用: https ://github.com/lolluslollus/Utilz/blob/master/Utilz/SwitchableObservableCollection.cs

于 2016-02-09T23:07:34.173 回答