在我的程序中,我有一个抽象类ObservableKeyedCollection<TKey, TItem>
,它继承自KeyedCollection<TKey, TItem>
并实现INotifyCollectionChanged
.
这个抽象类的实现绑定到一个ListBox
. 在此ListBox
,我通过双击编辑项目,并在接受后,从该ObservableKeyedCollection<TKey, TItem>
实现中删除已编辑项目的旧实例,并添加已修改的新实例。
在 Windows 10 创意者更新(1703,内部版本号 15063.250)之前,这一切都运行良好。自更新以来,ObservableKeyedCollection<TKey, TItem>
开始抛出InvalidOperationException
s 并显示以下消息:
调用线程无法访问此对象,因为不同的线程拥有它。
我没有在代码的这个区域使用任何异步操作。
整个堆栈跟踪会太长,但这里是开头的顶部OnCollectionChanged
:
在 System.Windows.Threading.Dispatcher.VerifyAccess() 在 System.Windows.Threading.DispatcherObject.VerifyAccess() 在 System.Windows.DependencyObject.GetValue(DependencyProperty dp) 在 System.Windows.Controls.Primitives.Selector.GetIsSelected(DependencyObject元素) 在 System.Windows.Controls.Primitives.Selector.SelectionChanger.CreateDeltaSelectionChange(List'1 unselectedItems, List'1 selectedItems) 在 System.Windows.Windows.Controls.Primitives.Selector.ItemSetIsSelected(ItemInfo info, Boolean value) .Controls.Primitives.Selector.SelectionChanger.End() 在 System.Windows.Controls.Primitives.Selector.RemoveFromSelection(NotifyCollectionChangedEventArgs e) 在 System.Windows.Controls.Primitives.Selector.OnItemsChanged(NotifyCollectionChangedEventArgs e) 在 System.Windows.Controls .ItemsControl.OnItemCollectionChanged2(Object sender, NotifyCollectionChangedEventArgs e) 在 System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e) 在 System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args) 在 System.Windows.Controls.ItemCollection。 OnViewCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) at System.Windows.WeakEventManager.ListenerList'1.DeliverEvent(Object sender, EventArgs e, Type managerType) at System.Windows.WeakEventManager.DeliverEventToList(Object sender, EventArgs args, ListenerList list) at System .Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args) at System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object sender,NotifyCollectionChangedEventArgs args) 在 System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args) 在 System.Windows.Data.ListCollectionView.ProcessCollectionChangedWithAdjustedIndex(NotifyCollectionChangedEventArgs args, Int32adjustedOldIndex, Int32adjustedNewIndex) 在 System.Windows.Data.ListCollectionView.ProcessCollectionChangedargs ) 在 System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args) 在 TetheredSun.ObservableKeyedCollection'2.OnCollectionChanged(NotifyCollectionChangedEventArgs e) 在 e:\Phil\Programozás\Modulok\TetheredSun.1.0\TetheredSun\ObservableKeyedCollection.cs,行号:68 at TetheredSun.ObservableKeyedCollection`2.RemoveItem(Int32 index) at [...]]]]]CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args) 在 System.Windows.Data.ListCollectionView.ProcessCollectionChangedWithAdjustedIndex(NotifyCollectionChangedEventArgs args, Int32adjustedOldIndex, Int32adjustedNewIndex) 在 System.Windows.Data.ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args) 在 System.Windows.Data.Colle OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args) at TetheredSun.ObservableKeyedCollection'2.OnCollectionChanged(NotifyCollectionChangedEventArgs e) at e:\Phil\Programozás\Modulok\TetheredSun.1.0\TetheredSun\ObservableKeyedCollection.cs,行号:68 at TetheredSun.ObservableKeyedColle .RemoveItem(Int32 索引)在 [...]CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args) 在 System.Windows.Data.ListCollectionView.ProcessCollectionChangedWithAdjustedIndex(NotifyCollectionChangedEventArgs args, Int32adjustedOldIndex, Int32adjustedNewIndex) 在 System.Windows.Data.ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args) 在 System.Windows.Data.Colle OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args) at TetheredSun.ObservableKeyedCollection'2.OnCollectionChanged(NotifyCollectionChangedEventArgs e) at e:\Phil\Programozás\Modulok\TetheredSun.1.0\TetheredSun\ObservableKeyedCollection.cs,行号:68 at TetheredSun.ObservableKeyedColle .RemoveItem(Int32 索引)在 [...]ListCollectionView.ProcessCollectionChangedWithAdjustedIndex(NotifyCollectionChangedEventArgs args, Int32adjustedOldIndex, Int32adjustedNewIndex) 在 System.Windows.Data.ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args) 在 System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args) 在 Tether2 .OnCollectionChanged(NotifyCollectionChangedEventArgs e) 在 e:\Phil\Programozás\Modulok\TetheredSun.1.0\TetheredSun\ObservableKeyedCollection.cs,行号:68 在 TetheredSun.ObservableKeyedCollection`2.RemoveItem(Int32 index) 在 [...]ListCollectionView.ProcessCollectionChangedWithAdjustedIndex(NotifyCollectionChangedEventArgs args, Int32adjustedOldIndex, Int32adjustedNewIndex) 在 System.Windows.Data.ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args) 在 System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args) 在 Tether2 .OnCollectionChanged(NotifyCollectionChangedEventArgs e) 在 e:\Phil\Programozás\Modulok\TetheredSun.1.0\TetheredSun\ObservableKeyedCollection.cs,行号:68 在 TetheredSun.ObservableKeyedCollection`2.RemoveItem(Int32 index) 在 [...]ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args) 在 System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args) 在 TetheredSun.ObservableKeyedCollection'2.OnCollectionChanged(NotifyCollectionChangedEventArgs e) 在 e:\Phil\Programozás\Modulok\TetheredSun1。 TetheredSun\ObservableKeyedCollection.cs,行号:68 在 TetheredSun.ObservableKeyedCollection`2.RemoveItem(Int32 index) at [...]ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args) 在 System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args) 在 TetheredSun.ObservableKeyedCollection'2.OnCollectionChanged(NotifyCollectionChangedEventArgs e) 在 e:\Phil\Programozás\Modulok\TetheredSun1。 TetheredSun\ObservableKeyedCollection.cs,行号:68 在 TetheredSun.ObservableKeyedCollection`2.RemoveItem(Int32 index) at [...]0\TetheredSun\ObservableKeyedCollection.cs,行号:68 在 TetheredSun.ObservableKeyedCollection`2.RemoveItem(Int32 index) at [...]0\TetheredSun\ObservableKeyedCollection.cs,行号:68 在 TetheredSun.ObservableKeyedCollection`2.RemoveItem(Int32 index) at [...]
编辑1:
这是在创作者更新之前正常工作的违规代码部分(覆盖KeyedCollection<TKey, TItem>.RemoveItem(int index)
):
protected override void RemoveItem(int index)
{
TItem item = this[index];
base.RemoveItem(index);
if (deferNotifyCollectionChanged) return;
if (item is IList) {
// Listeners do not support multiple item changes, and our item happens to be an IList, so we must raise NotifyCollectionChangedAction.Reset.
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
} else {
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
}
OnPropertyChanged(new PropertyChangedEventArgs("Count"));
}
只有当我OnCollectionChanged
使用NotifyCollectionChangedAction.Remove
操作调用时,才会出现问题。将其替换为NotifyCollectionChangedAction.Reset
似乎可以避免异常:
protected override void RemoveItem(int index)
{
TItem item = this[index];
base.RemoveItem(index);
if (deferNotifyCollectionChanged) return;
// No exception thrown so far if I stick to NotifyCollectionChangedAction.Reset:
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
OnPropertyChanged(new PropertyChangedEventArgs("Count"));
}
我试图用Dispatcher
这里看到的问题来解决这个问题:https ://stackoverflow.com/a/22026686/2659699但是虽然我的调度程序不为空,但它的CheckAccess()
计算结果为真,并且我在NotifyCollectionChangedEventHandler.Invoke()
.
非常感谢您的想法和帮助。