最近、私は本当に悪いWPFバグにぶつかってきました。私は、Microsoft Connectのthis bugと同じだと思います。 ViewModelにはItemsControlに内を移動するためのアイテムを引き起こす任意のプロパティまたはコレクションへの変更をトリガすると、2010年WPF Freezableバグの回避策?
基本的にはVisual Studioを使用
当社のアプリケーションのターゲット.NET 4.0クライアントのプロファイルは、例外はそのチャンスがあります以下が投げられる。それはいつも起こるとは限らず、違う時期に異なるトリガーに基づいて起こるようです。アプリケーションを起動した直後の可能性が高いようです。例外を叩かずに数分間使用することができれば、おそらくそのアプリケーションインスタンス中にヒットすることはありません。
Connectバグレポートと同様に、私は{DynamicResource key}
を使用してResourceDictionary
からSolidColorBrush
をロードしています。いくつかの辞書は手動で読み込まれます(テーマサポートのため)。私は手動でそれらの辞書のすべてを凍結しようとしましたが、それは助けには見えません。
UserControl
をメインウィンドウに追加したときに例外が頻繁に発生しました。その中には、ItemsControlsがObservableCollection
にバインドされています。以前は、50回中に例外1回しか見ませんでしたが、今は5回のうち4回、プログラムを使用しています。
回避策の候補がありますか? Connectのバグは、これが次の.NETリリースで修正される可能性があることを示していますが、このバグは今では基本的にアプリケーションを使用できなくしています。
System.InvalidOperationException: Specified value of type 'System.Windows.Media.SolidColorBrush' must have IsFrozen set to false to modify. at System.Windows.Freezable.WritePreamble() at System.Windows.Freezable.remove_Changed(EventHandler value) at System.Windows.ResourceReferenceExpression.ResourceReferenceExpressionWeakContainer.RemoveChangedHandler() at System.Windows.ResourceReferenceExpression.ResourceReferenceExpressionWeakContainer.InvalidateTargetSubProperty(Object sender, EventArgs args) at System.Windows.Freezable.FireChanged() at System.Windows.Freezable.Freeze(Boolean isChecking) at System.Windows.Freezable.Freeze() at System.Windows.Freezable.System.Windows.ISealable.Seal() at System.Windows.StyleHelper.SealIfSealable(Object value) at System.Windows.StyleHelper.GetChildValueHelper(UncommonField`1 dataField, ItemStructList`1& valueLookupList, DependencyProperty dp, DependencyObject container, FrameworkObject child, Int32 childIndex, Boolean styleLookup, EffectiveValueEntry& entry, ValueLookupType& sourceType, FrameworkElementFactory templateRoot) at System.Windows.StyleHelper.GetChildValue(UncommonField`1 dataField, DependencyObject container, Int32 childIndex, FrameworkObject child, DependencyProperty dp, FrugalStructList`1& childRecordFromChildIndex, EffectiveValueEntry& entry, ValueLookupType& sourceType, FrameworkElementFactory templateRoot) at System.Windows.StyleHelper.GetValueFromTemplatedParent(DependencyObject container, Int32 childIndex, FrameworkObject child, DependencyProperty dp, FrugalStructList`1& childRecordFromChildIndex, FrameworkElementFactory templateRoot, EffectiveValueEntry& entry) at System.Windows.FrameworkElement.GetValueFromTemplatedParent(DependencyProperty dp, EffectiveValueEntry& entry) at System.Windows.FrameworkElement.GetRawValue(DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry& entry) at System.Windows.FrameworkElement.EvaluateBaseValueCore(DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry& newEntry) at System.Windows.DependencyObject.EvaluateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry newEntry, OperationType operationType) at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType) at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp) at System.Windows.StyleHelper.InvalidateResourceDependentsForChild(DependencyObject container, DependencyObject child, Int32 childIndex, ResourcesChangeInfo info, FrameworkTemplate parentTemplate) at System.Windows.TreeWalkHelper.InvalidateStyleAndReferences(DependencyObject d, ResourcesChangeInfo info, Boolean containsTypeOfKey) at System.Windows.TreeWalkHelper.OnResourcesChanged(DependencyObject d, ResourcesChangeInfo info, Boolean raiseResourceChangedEvent) at System.Windows.FrameworkElement.OnAncestorChangedInternal(TreeChangeInfo parentTreeState) at System.Windows.TreeWalkHelper.OnAncestorChanged(DependencyObject d, TreeChangeInfo info) at System.Windows.DescendentsWalker`1._VisitNode(DependencyObject d) at MS.Internal.PrePostDescendentsWalker`1._VisitNode(DependencyObject d) at System.Windows.DescendentsWalker`1.VisitNode(FrameworkElement fe) at System.Windows.DescendentsWalker`1.VisitNode(DependencyObject d) at System.Windows.DescendentsWalker`1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren) at System.Windows.DescendentsWalker`1.IterateChildren(DependencyObject d) at System.Windows.DescendentsWalker`1.StartWalk(DependencyObject startNode, Boolean skipStartNode) at MS.Internal.PrePostDescendentsWalker`1.StartWalk(DependencyObject startNode, Boolean skipStartNode) at System.Windows.TreeWalkHelper.InvalidateOnTreeChange(FrameworkElement fe, FrameworkContentElement fce, DependencyObject parent, Boolean isAddOperation) at System.Windows.FrameworkElement.OnVisualParentChanged(DependencyObject oldParent) at System.Windows.Media.Visual.FireOnVisualParentChanged(DependencyObject oldParent) at System.Windows.Media.Visual.RemoveVisualChild(Visual child) at System.Windows.Media.VisualCollection.DisconnectChild(Int32 index) at System.Windows.Media.VisualCollection.Clear() at System.Windows.Controls.UIElementCollection.ClearInternal() at System.Windows.Controls.Panel.ClearChildren() at System.Windows.Controls.Panel.OnItemsChangedInternal(Object sender, ItemsChangedEventArgs args) at System.Windows.Controls.Panel.OnItemsChanged(Object sender, ItemsChangedEventArgs args) at System.Windows.Controls.ItemContainerGenerator.OnRefresh() at System.Windows.Controls.ItemContainerGenerator.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args) at System.Windows.Controls.ItemContainerGenerator.System.Windows.IWeakEventListener.ReceiveWeakEvent(Type managerType, Object sender, EventArgs e) 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) at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e) at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args) at System.Windows.Controls.ItemCollection.System.Windows.IWeakEventListener.ReceiveWeakEvent(Type managerType, Object sender, EventArgs e) 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) at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args) at System.Windows.Data.ListCollectionView.RefreshOverride() at System.Windows.Data.CollectionView.Refresh() at System.Windows.Data.CollectionView.EndDefer() at System.Windows.Data.CollectionView.DeferHelper.Dispose() at System.Windows.Controls.ItemCollection.SetCollectionView(CollectionView view) at System.Windows.Controls.ItemCollection.SetItemsSource(IEnumerable value) at System.Windows.Controls.ItemsControl.OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e) at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e) at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args) at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType) at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp) at System.Windows.Data.BindingExpressionBase.Invalidate(Boolean isASubPropertyChange) at System.Windows.Data.BindingExpression.TransferValue(Object newValue, Boolean isASubPropertyChange) at System.Windows.Data.BindingExpression.ScheduleTransfer(Boolean isASubPropertyChange) at MS.Internal.Data.ClrBindingWorker.NewValueAvailable(Boolean dependencySourcesChanged, Boolean initialValue, Boolean isASubPropertyChange) at MS.Internal.Data.PropertyPathWorker.UpdateSourceValueState(Int32 k, ICollectionView collectionView, Object newValue, Boolean isASubPropertyChange) at MS.Internal.Data.ClrBindingWorker.OnSourcePropertyChanged(Object o, String propName) at MS.Internal.Data.PropertyPathWorker.System.Windows.IWeakEventListener.ReceiveWeakEvent(Type managerType, Object sender, EventArgs e) at System.Windows.WeakEventManager.DeliverEventToList(Object sender, EventArgs args, ListenerList list) at System.ComponentModel.PropertyChangedEventManager.OnPropertyChanged(Object sender, PropertyChangedEventArgs args) at ***.ViewModelBase.OnPropertyChanged(String name) in c:\***\ViewModelBase.cs:line 17 .....
EDIT: 我々は、単に私たちのViewModel基本クラスのPropertyChangedイベントの内部でスローされたInvalidOperationException
のを抑制しようとしました。それは例外の数を幾分減らすように見えましたが、今ではObservableCollection
のCollectionChanged
イベントでそれらをヒットしました。
Dispatcher.Invokeを使用して、別の優先順位でOnPropertyChangedをコード内で呼び出そうとしましたか?それはときどき私が影響を与えるために使用するものです - 少しランダムに私は同意します:-)競合条件のWPF ... –
野生の推測ですが、インスタンス化時に参照されているブラシリソースをすべてフリーズできますか?あなたはここでそれを行う方法を読むことができます:http://stackoverflow.com/questions/799890/how-can-wpf-objects-deriving-from-freezable-be-frozen-in-xaml –
また、 ObservableCollectionをUIスレッドから変更するだけですか? –