微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

wpf 中带有 BindingOperations.EnableCollectionSynchronization 的 System.InvalidOperationException

如何解决wpf 中带有 BindingOperations.EnableCollectionSynchronization 的 System.InvalidOperationException

我们有一个 AsyncObservableCollection 类,它继承自 wpf 应用程序中的 ObservableCollection。 这门课有:

public dispatcher dispatcher
{
   get
   {
       if (_dispatcher == null)
       {
           if (Application.Current != null)
           {
               _dispatcher = Application.Current.dispatcher;
           }
           else
           {
               _dispatcher = dispatcher.Currentdispatcher;
           }
       }
       return _dispatcher;
   }
   set
   {
       _dispatcher = value;
   }
}

protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
   if (!dispatcher.CheckAccess())
   {
       dispatcher.BeginInvoke(
           new Action<NotifyCollectionChangedEventArgs>(OnCollectionChanged),e);
       return;
   }
   base.OnCollectionChanged(e);
}


protected override void OnPropertyChanged(PropertyChangedEventArgs e)
{
   if (!dispatcher.CheckAccess())
   {
       dispatcher.BeginInvoke(new Action<PropertyChangedEventArgs>(OnPropertyChanged),e);
       return;
   }

   base.OnPropertyChanged(e);
}

还有另一个类 RangeObservableCollection 继承自这个 AsyncObservableCollectionClass,里面只有这个

private bool _suppressNotification;

public void ReplaceRange(IEnumerable<T> list)
{
    _suppressNotification = true;
    Clear();
    if (list != null)
    {
        foreach (T item in list)
        {
            Add(item);
        }
    }
    _suppressNotification = false;
    OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}



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

现在我尝试使用BindingOperations.EnableCollectionSynchronization。 然后在我们的 ListviewmodelBase.cs 里面 创建了一个这样的锁对象

private readonly static object _storiesCollectionLock = new object();

在我们的 ListviewmodelBase 的构造函数中 我们正在创建 RangeObservableCollection 并绑定 BindingOperations.CollectionRegistering

protected ListviewmodelBase()
{
    _storiesCollection = new RangeObservableCollection<StoryInfoviewmodel>();
    BindingOperations.CollectionRegistering += BindingOperations_CollectionRegistering;
}

private void BindingOperations_CollectionRegistering(object sender,CollectionRegisteringEventArgs e)
{
    if (e.Collection == _storiesCollection)
    {
        dispatcher.BeginInvoke(new Action(() =>
        {
            BindingOperations.EnableCollectionSynchronization(_storiesCollection,_storiesCollectionLock);
        }));
    }
}

然后在我们项目中的任何地方使用这个 _storiesCollection,我都将它包装在一个使用这个 _storiesCollectionLock 对象的锁中。甚至锁定正在填充此可观察集合的 ListCollectionView。 在 ListviewmodelBase 中为 _storiesCollection 和 _storiesCollectionLock 对象创建属性

public RangeObservableCollection<StoryInfoviewmodel> StoriesCollection
{
    get
    {
        lock (StoriesCollectionLock())
        {
            return _storiesCollection;
        }
    }
}

public static object StoriesCollectionLock()
{
    return _storiesCollectionLock;
}

然后当我尝试在工作线程上插入这个 StoriesCollection 时,在我的 add 方法中的一个单独的 StoryListviewmodel 中

lock (StoriesCollectionLock())
{
   StoriesCollection.Insert(0,storyVM);
}

我在 AsyncObservableCollection 类的 OnCollectionChanged 中遇到异常

system.invalidOperationException: 'Added item does not appear at given index '0'.'

也得到异常 Message = "Cannot change ObservableCollection during a CollectionChanged event.",下面是这个堆栈跟踪

at System.Collections.ObjectModel.ObservableCollection1.CheckReentrancy() at System.Collections.ObjectModel.ObservableCollection1.InsertItem(Int32 index,T item) 在 System.Collections.ObjectModel.Collection`1.Insert(Int32 index,T item)

system.invalidOperationException: ''1510' index in collection change event is not valid for collection of size '1500'.'

有人可以帮忙吗,我在这里做错了什么或遗漏了什么? 还是 EnableCollectionSynchronization 的已知问题?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。