从后台线程+ WPF +静默更新更新可观察集合

时间:2014-07-16 06:44:07

标签: wpf multithreading observablecollection

我计划有一个线程安全的可观察集合,我在后台运行任务,并在使用调度程序获取结果时更新UI。

我从互联网上下载了ThreadSafe。但我有一个小问题。我希望在UI上进行静默更新。由于用户已经在工作或选择绑定集合,我不想打扰用户选择的条目。换句话说,我想在新邮件到达时添加类似于Microsoft Outlook的条目。

这是否可行,是否有这样的例子。

由于

1 个答案:

答案 0 :(得分:0)

您可以从ObservableCollection获取派生类并覆盖它OnCollectionChanged函数,并在需要时引发它处理程序。以下是代码。

 public class ThreadSafeObservableCollection<T> : ObservableCollection<T>
 {
    public override event NotifyCollectionChangedEventHandler CollectionChanged;
    private bool suspendCollectionChangeNotification;

  protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {

                if (!this.suspendCollectionChangeNotification)
                {
                    NotifyCollectionChangedEventHandler eventHandler = CollectionChanged;
                    if (eventHandler != null)
                    {
                        Delegate[] delegates = eventHandler.GetInvocationList();

                        // Walk through invocation list
                        bool isEventInvoked = false;
                        foreach (NotifyCollectionChangedEventHandler handler in delegates)
                        {
                            isEventInvoked = false;
                            if (handler.Target is DispatcherObject)
                            {
                                DispatcherObject dispatcherObject = handler.Target as DispatcherObject;

                                // This check is to make sure if the call on a different thread than the dispatcher.
                                if (dispatcherObject != null && dispatcherObject.CheckAccess() == false)
                                {
                                    // Invoke handler in the target dispatcher's thread
                                    // Intentionally called begin invoke because there is a problem with Dispatcher.Invoke that it hangs when
                                    // called simultaneously
                                    dispatcherObject.Dispatcher.BeginInvoke(DispatcherPriority.DataBind, handler, this, e);
                                    isEventInvoked = true;
                                }
                            }

                            if (!isEventInvoked)
                            {
                                handler(this, e);
                            }
                        }
                    }
                }

}