私は最近、本当にひどい WPF バグに遭遇しました。Microsoft Connectのこのバグと同じだと思います。
このアプリケーションは、Visual Studio 2010 を使用して .NET 4.0 Client Profile をターゲットにしています。
基本的に、ViewModel が ItemsControl 内で項目を移動させるプロパティまたはコレクションへの変更をトリガーすると、以下の例外がスローされる可能性があります。常に発生するとは限らず、さまざまなトリガーに基づいてさまざまな時期に発生するようです。アプリ起動直後の方が多いようです。例外をヒットせずに数分間使用できる場合、そのアプリケーション インスタンス中にヒットすることはおそらくないでしょう。
Connect のバグ レポートと同様{DynamicResource key}
にSolidColorBrush
、ResourceDictionary
. 一部の辞書は手動でロードされます (テーマのサポートのため)。これらの辞書のすべてを手動でフリーズしようとしましたが、効果がないようです。
UserControl
s にバインドされた ItemsControls を含むいくつかの s をメイン ウィンドウに追加すると、最近、例外が頻繁に発生するようになりましたObservableCollection
。以前は、例外は 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 引数) で 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、ブール式 styleLookup、EffectiveValueEntry& エントリ、ValueLookupType& sourceType、FrameworkElementFactory templateRoot) で System.Windows.StyleHelper.GetChildValue (UncommonField`1 dataField、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、ブール値 coerceWithDeferredReference、ブール値 coerceWithCurrentValue、OperationType operationType) で System.Windows.DependencyObject.InvalidateProperty (DependencyProperty dp) で System.Windows.StyleHelper.InvalidateResourceDependentsForChild (DependencyObject コンテナー、DependencyObject 子、Int32 childIndex、ResourcesChangeInfo 情報、FrameworkTemplate 親テンプレート) で System.Windows.TreeWalkHelper.InvalidateStyleAndReferences (DependencyObject d、ResourcesChangeInfo 情報、ブール値の containsTypeOfKey) で System.Windows.TreeWalkHelper.OnResourcesChanged (DependencyObject d、ResourcesChangeInfo 情報、Boolean raiseResourceChangedEvent) で System.Windows.FrameworkElement.OnAncestorChangedInternal (TreeChangeInfo 親ツリー状態) で 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、ブール値 hasLogicalChildren) で System.Windows.DescendentsWalker`1.IterateChildren (DependencyObject d) で System.Windows.DescendentsWalker`1.StartWalk (DependencyObject startNode、ブール値の skipStartNode) で MS.Internal.PrePostDescendentsWalker`1.StartWalk (DependencyObject startNode、ブール値の 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 args) で System.Windows.Controls.Panel.OnItemsChanged (オブジェクトの送信者、ItemsChangedEventArgs args) で System.Windows.Controls.ItemContainerGenerator.OnRefresh() で System.Windows.Controls.ItemContainerGenerator.OnCollectionChanged (オブジェクトの送信者、NotifyCollectionChangedEventArgs args) で 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 args) で 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 args) で 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 args) で System.Windows.DependencyObject.UpdateEffectiveValue (EntryIndex entryIndex、DependencyProperty dp、PropertyMetadata メタデータ、EffectiveValueEntry oldEntry、EffectiveValueEntry& newEntry、ブール値 coerceWithDeferredReference、ブール値 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 (ブール値の dependencySourcesChanged、ブール値の initialValue、ブール値の isASubPropertyChange) で MS.Internal.Data.PropertyPathWorker.UpdateSourceValueState (Int32 k、ICollectionView collectionView、オブジェクト 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 引数) で at ***.ViewModelBase.OnPropertyChanged(String name) in c:\***\ViewModelBase.cs:line 17 .....
InvalidOperationException
編集: また、ViewModel 基本クラスの PropertyChanged イベント内でスローされた s を単純に抑制しようとしました。ObservableCollection
これにより、例外の数がいくらか減ったように見えましたが、今はのCollectionChanged
イベントでヒットするだけです。