C#:ObservableCollection-为什么虚拟"CollectionChanged"事件? [英] C#: ObservableCollection - why virtual “CollectionChanged” event?

查看:262
本文介绍了C#:ObservableCollection-为什么虚拟"CollectionChanged"事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么CollectioncChanged事件在ObservableCollection中是虚拟?我们有虚拟的OnCollectionChanged方法,该方法足以覆盖事件调用权吗?

Why CollectionChanged event is virtual in ObservableCollection? We have virtual OnCollectionChanged method, which should be enough to override event call right?

我看不到有任何用法,虚拟事件也是邪恶的.虚假使用虚拟事件会带来很多逻辑问题,但是虚拟事件甚至存在于框架中.

I don't see any usage of this, and also virtual events are evil. ungainly usage of virtual events can bring a lot of logical issues, but however virtual events exists even in framework.

这是不好的设计,还是有人用真实的字眼来使用它?

Is this just bad design or anyone use this in real-word?

推荐答案

我们可以就基类和设计进行辩论,但这不是一个直接的/学术的答案,而是更多示例.我个人觉得很棒,可以扩展ObservableCollection并覆盖OnCollectionChanged. ObservableCollection非常健谈,每次添加/删除项目时,它都会用属性已更改的消息轰击UI线程并放慢它的速度(例如,在数据网格中,其中的每个绑定都将被更新).因此,据我所知,很多人都扩展了ObservableCollection来抑制此类通知,直到他们完成添加项为止.仅仅是因为WPF控制着DataGrids/ListViews等.所以对CollectionChanged进行响应就可以了.

We can debate about base classes and design, but here's a not direct/scholastic answer, but more of an example. I personally find it great that I could extend ObservableCollection and override OnCollectionChanged. ObservableCollection is very chatty, every time you add/remove items it bombards the UI thread with property changed messages and slows it down (in the datagrid, for example, every binding in it to be updated). So, as far as I know many people extend the ObservableCollection to suppress such notifications until they are done adding items. Just because WPF controls DataGrids/ListViews etc.. respond to CollectionChanged this works.

这是用法,我刷新数据,而不是一次添加一个项目,而是填充一个List,然后一次用它重置ObservableCollection,这极大地提高了UI响应速度:

here's the usage, I refresh my data and instead of adding one item at a time, I populate a List then I reset the ObservableCollection with it just once which speeds up UI responsiveness enormously:

private void OnExecuteRefreshCompleted(IEnumerable<MyObject> result)
{
UiUtilities.OnUi(() => { _myObservableCollectionField.Reset(result, true);              
        });

这是我的延伸班级:

public class ObservableCollectionExtended<T> : ObservableCollection<T>
{
    private bool _suppressNotification;

            //without virtual , I couldn't have done this override
    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (!_suppressNotification)
            base.OnCollectionChanged(e);
    }

    public void Clear(bool suppressNotificationUntillComplete)
    {
        _suppressNotification = suppressNotificationUntillComplete;

        Clear();

        _suppressNotification = false;
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

    public void ClearItems(bool suppressNotificationUntillComplete)
    {
        _suppressNotification = suppressNotificationUntillComplete;

        base.ClearItems();

        _suppressNotification = false;
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

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

        _suppressNotification = suppressNotificationUntillComplete;

        foreach (T item in list)
            Add(item);

        _suppressNotification = false;
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

    /// <summary>
    /// clears old items, and new ones
    /// </summary>
    /// <param name="list"></param>
    /// <param name="suppressNotificationUntillComplete"></param>
    public void Reset(IEnumerable<T> list, bool suppressNotificationUntillComplete)
    {
        if (list == null)
            throw new ArgumentNullException("list");

        _suppressNotification = suppressNotificationUntillComplete;

        Clear();

        foreach (T item in list)
            Add(item);

        _suppressNotification = false;
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }
}

这篇关于C#:ObservableCollection-为什么虚拟"CollectionChanged"事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆