我最近遇到了一个非常糟糕的 WPF 错误。我认为这与Microsoft Connect 上的这个错误相同。
我们的应用程序使用 Visual Studio 2010 以 .NET 4.0 客户端配置文件为目标。
基本上,当 ViewModel 触发对导致项目在 ItemsControl 中移动的任何属性或集合的更改时,有可能会引发以下异常。它并不总是发生,而且似乎是基于不同时间的不同触发器而发生的。似乎更有可能在启动应用程序后不久。如果您可以使用它几分钟而不会遇到异常,那么您可能永远不会在该应用程序实例期间遇到异常。
{DynamicResource key}
就像Connect错误报告一样,我正在使用SolidColorBrush
从ResourceDictionary
. 一些字典是手动加载的(用于主题支持)。我尝试手动冻结这些词典中的所有内容,但似乎没有帮助。
最近,当我在主窗口中添加了几个UserControl
s 并将其中的 ItemsControls 绑定到ObservableCollection
s 时,异常变得更加频繁。以前,我只会在 50 次中看到异常 1 次,但现在我在使用该程序的 5 次中看到了 4 次。
有没有人对解决方法有任何想法?Connect 错误表明这可能会在下一个 .NET 版本(无论何时)中得到修复,但这个错误使我们的应用程序现在基本上无法使用。
System.InvalidOperationException:“System.Windows.Media.SolidColorBrush”类型的指定值必须将 IsFrozen 设置为 false 才能修改。 在 System.Windows.Freezable.WritePreamble() 在 System.Windows.Freezable.remove_Changed(EventHandler 值) 在 System.Windows.ResourceReferenceExpression.ResourceReferenceExpressionWeakContainer.RemoveChangedHandler() 在 System.Windows.ResourceReferenceExpression.ResourceReferenceExpressionWeakContainer.InvalidateTargetSubProperty(对象发件人,EventArgs args) 在 System.Windows.Freezable.FireChanged() 在 System.Windows.Freezable.Freeze(布尔 isChecking) 在 System.Windows.Freezable.Freeze() 在 System.Windows.Freezable.System.Windows.ISealable.Seal() 在 System.Windows.StyleHelper.SealIfSealable(对象值) 在 System.Windows.StyleHelper.GetChildValueHelper(UncommonField`1 dataField,ItemStructList`1& valueLookupList,DependencyProperty dp,DependencyObject 容器,FrameworkObject 子项,Int32 childIndex,布尔样式查找,EffectiveValueEntry& 条目,ValueLookupType& sourceType,FrameworkElementFactory templateRoot) 在 System.Windows.StyleHelper.GetChildValue(UncommonField`1 数据字段,DependencyObject 容器,Int32 childIndex,FrameworkObject 子项,DependencyProperty dp,FrugalStructList`1& childRecordFromChildIndex,EffectiveValueEntry& 条目,ValueLookupType& sourceType,FrameworkElementFactory templateRoot) 在 System.Windows.StyleHelper.GetValueFromTemplatedParent(DependencyObject 容器、Int32 childIndex、FrameworkObject 子项、DependencyProperty dp、FrugalStructList`1& childRecordFromChildIndex、FrameworkElementFactory templateRoot、EffectiveValueEntry& 条目) 在 System.Windows.FrameworkElement.GetValueFromTemplatedParent(DependencyProperty dp,EffectiveValueEntry& 条目) 在 System.Windows.FrameworkElement.GetRawValue(DependencyProperty dp,PropertyMetadata 元数据,EffectiveValueEntry& 条目) 在 System.Windows.FrameworkElement.EvaluateBaseValueCore(DependencyProperty dp,PropertyMetadata 元数据,EffectiveValueEntry & newEntry) 在 System.Windows.DependencyObject.EvaluateEffectiveValue(EntryIndex entryIndex,DependencyProperty dp,PropertyMetadata 元数据,EffectiveValueEntry oldEntry,EffectiveValueEntry newEntry,OperationType operationType) 在 System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex、DependencyProperty dp、PropertyMetadata 元数据、EffectiveValueEntry oldEntry、EffectiveValueEntry& newEntry、Boolean coerceWithDeferredReference、Boolean coerceWithCurrentValue、OperationType operationType) 在 System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp) 在 System.Windows.StyleHelper.InvalidateResourceDependentsForChild(DependencyObject 容器,DependencyObject 子项,Int32 childIndex,ResourcesChangeInfo 信息,FrameworkTemplate parentTemplate) 在 System.Windows.TreeWalkHelper.InvalidateStyleAndReferences(DependencyObject d,ResourcesChangeInfo 信息,布尔 containsTypeOfKey) 在 System.Windows.TreeWalkHelper.OnResourcesChanged(DependencyObject d,ResourcesChangeInfo 信息,布尔 raiseResourceChangedEvent) 在 System.Windows.FrameworkElement.OnAncestorChangedInternal(TreeChangeInfo parentTreeState) 在 System.Windows.TreeWalkHelper.OnAncestorChanged(DependencyObject d,TreeChangeInfo 信息) 在 System.Windows.DescendentsWalker`1._VisitNode(DependencyObject d) 在 MS.Internal.PrePostDescendentsWalker`1._VisitNode(DependencyObject d) 在 System.Windows.DescendentsWalker`1.VisitNode(FrameworkElement fe) 在 System.Windows.DescendentsWalker`1.VisitNode(DependencyObject d) 在 System.Windows.DescendentsWalker`1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren) 在 System.Windows.DescendentsWalker`1.IterateChildren(DependencyObject d) 在 System.Windows.DescendentsWalker`1.StartWalk(DependencyObject startNode, Boolean skipStartNode) 在 MS.Internal.PrePostDescendentsWalker`1.StartWalk(DependencyObject startNode, Boolean skipStartNode) 在 System.Windows.TreeWalkHelper.InvalidateOnTreeChange(FrameworkElement fe,FrameworkContentElement fce,DependencyObject 父级,布尔 isAddOperation) 在 System.Windows.FrameworkElement.OnVisualParentChanged(DependencyObject oldParent) 在 System.Windows.Media.Visual.FireOnVisualParentChanged(DependencyObject oldParent) 在 System.Windows.Media.Visual.RemoveVisualChild(视觉孩子) 在 System.Windows.Media.VisualCollection.DisconnectChild(Int32 索引) 在 System.Windows.Media.VisualCollection.Clear() 在 System.Windows.Controls.UIElementCollection.ClearInternal() 在 System.Windows.Controls.Panel.ClearChildren() 在 System.Windows.Controls.Panel.OnItemsChangedInternal(对象发送者,ItemsChangedEventArgs 参数) 在 System.Windows.Controls.Panel.OnItemsChanged(对象发送者,ItemsChangedEventArgs args) 在 System.Windows.Controls.ItemContainerGenerator.OnRefresh() 在 System.Windows.Controls.ItemContainerGenerator.OnCollectionChanged(对象发送者,NotifyCollectionChangedEventArgs 参数) 在 System.Windows.Controls.ItemContainerGenerator.System.Windows.IWeakEventListener.ReceiveWeakEvent(类型 managerType,对象发送者,EventArgs e) 在 System.Windows.WeakEventManager.DeliverEventToList(对象发送者,EventArgs 参数,ListenerList 列表) 在 System.Windows.WeakEventManager.DeliverEvent(对象发送者,EventArgs 参数) 在 System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(对象发送者,NotifyCollectionChangedEventArgs 参数) 在 System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(对象发送者,NotifyCollectionChangedEventArgs e) 在 System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs 参数) 在 System.Windows.Controls.ItemCollection.System.Windows.IWeakEventListener.ReceiveWeakEvent(类型 managerType,对象发送者,EventArgs e) 在 System.Windows.WeakEventManager.DeliverEventToList(对象发送者,EventArgs 参数,ListenerList 列表) 在 System.Windows.WeakEventManager.DeliverEvent(对象发送者,EventArgs 参数) 在 System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(对象发送者,NotifyCollectionChangedEventArgs 参数) 在 System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs 参数) 在 System.Windows.Data.ListCollectionView.RefreshOverride() 在 System.Windows.Data.CollectionView.Refresh() 在 System.Windows.Data.CollectionView.EndDefer() 在 System.Windows.Data.CollectionView.DeferHelper.Dispose() 在 System.Windows.Controls.ItemCollection.SetCollectionView(CollectionView 视图) 在 System.Windows.Controls.ItemCollection.SetItemsSource(IEnumerable 值) 在 System.Windows.Controls.ItemsControl.OnItemsSourceChanged(DependencyObject d,DependencyPropertyChangedEventArgs e) 在 System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e) 在 System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e) 在 System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs 参数) 在 System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex、DependencyProperty dp、PropertyMetadata 元数据、EffectiveValueEntry oldEntry、EffectiveValueEntry& newEntry、Boolean coerceWithDeferredReference、Boolean coerceWithCurrentValue、OperationType operationType) 在 System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp) 在 System.Windows.Data.BindingExpressionBase.Invalidate(布尔 isASubPropertyChange) 在 System.Windows.Data.BindingExpression.TransferValue(对象 newValue,布尔 isASubPropertyChange) 在 System.Windows.Data.BindingExpression.ScheduleTransfer(布尔 isASubPropertyChange) 在 MS.Internal.Data.ClrBindingWorker.NewValueAvailable(布尔依赖源更改,布尔初始值,布尔 isASubPropertyChange) 在 MS.Internal.Data.PropertyPathWorker.UpdateSourceValueState(Int32 k,ICollectionView 集合视图,对象 newValue,布尔 isASubPropertyChange) 在 MS.Internal.Data.ClrBindingWorker.OnSourcePropertyChanged(对象 o,字符串 propName) 在 MS.Internal.Data.PropertyPathWorker.System.Windows.IWeakEventListener.ReceiveWeakEvent(类型 managerType,对象发送者,EventArgs e) 在 System.Windows.WeakEventManager.DeliverEventToList(对象发送者,EventArgs 参数,ListenerList 列表) 在 System.ComponentModel.PropertyChangedEventManager.OnPropertyChanged(对象发送者,PropertyChangedEventArgs 参数) 在 c:\***\ViewModelBase.cs:line 17 中的 ***.ViewModelBase.OnPropertyChanged(String name) ......
编辑:我们还尝试简单地抑制InvalidOperationException
在 ViewModel 基类的 PropertyChanged 事件中抛出的任何 s 。这似乎在一定程度上减少了异常的数量,但现在我们只是在ObservableCollection
'CollectionChanged
事件中击中它们。