Upgrading to .NET 4.5: An ItemsControl is inconsistent with its items source

后端 未结 4 1770
心在旅途
心在旅途 2020-12-08 07:24

I\'m building an application, which uses many ItemControls(datagrids and listviews). In order to easily update these lists from background threads I used this extension to O

4条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-08 07:52

    To summarize this topic, this AsyncObservableCollection works with .NET 4 and .NET 4.5 WPF apps.

    using System;
    using System.Collections;
    using System.Collections.ObjectModel;
    using System.Collections.Specialized;
    using System.Linq;
    using System.Windows.Data;
    using System.Windows.Threading;
    
    namespace WpfAsyncCollection
    {
        public class AsyncObservableCollection : ObservableCollection
        {
            public override event NotifyCollectionChangedEventHandler CollectionChanged;
            private static object _syncLock = new object();
    
            public AsyncObservableCollection()
            {
                enableCollectionSynchronization(this, _syncLock);
            }
    
            protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
            {
                using (BlockReentrancy())
                {
                    var eh = CollectionChanged;
                    if (eh == null) return;
    
                    var dispatcher = (from NotifyCollectionChangedEventHandler nh in eh.GetInvocationList()
                                      let dpo = nh.Target as DispatcherObject
                                      where dpo != null
                                      select dpo.Dispatcher).FirstOrDefault();
    
                    if (dispatcher != null && dispatcher.CheckAccess() == false)
                    {
                        dispatcher.Invoke(DispatcherPriority.DataBind, (Action)(() => OnCollectionChanged(e)));
                    }
                    else
                    {
                        foreach (NotifyCollectionChangedEventHandler nh in eh.GetInvocationList())
                            nh.Invoke(this, e);
                    }
                }
            }
    
            private static void enableCollectionSynchronization(IEnumerable collection, object lockObject)
            {
                var method = typeof(BindingOperations).GetMethod("EnableCollectionSynchronization", 
                                        new Type[] { typeof(IEnumerable), typeof(object) });
                if (method != null)
                {
                    // It's .NET 4.5
                    method.Invoke(null, new object[] { collection, lockObject });
                }
            }
        }
    }
    

提交回复
热议问题