J'ai été frapper un très mauvais WPF bug récemment. Je pense que c'est la même chose que ce bug sur Microsoft Connect.
Notre application cible .NET 4.0 Client Profile à l'aide de Visual Studio 2010.
En gros, quand un ViewModel déclenche un changement de propriété de tout ou d'une collection qui provoque les éléments à déplacer dans un ItemsControl, il y a une chance que l'exception ci-dessous seront jetés. Il n'est pas toujours le cas et semble arriver basé sur des déclencheurs différents moments différents. Il semble plus probable que peu de temps après le démarrage de l'application. Si vous pouvez l'utiliser pour un couple de minutes sans toucher l'exception, vous aurez probablement jamais touché au cours de cette instance de l'application.
Comme le Connect rapport de bug, je suis à l'aide d' {DynamicResource key}
à la charge de l' SolidColorBrush
es à partir d'un ResourceDictionary
. Certains dictionnaires sont chargé manuellement (pour la thématisation de soutien). J'ai essayé manuellement bloquer tout dans ces dictionnaires, mais il ne semble pas avoir beaucoup aidé.
Les exceptions sont devenues beaucoup plus fréquentes ces derniers temps quand j'ai ajouté un couple de plus UserControl
s à la fenêtre principale qui ont ItemsControls en eux lié à l' ObservableCollection
s. Auparavant, j'avais seulement voir l'exception, 1 fois sur 50, mais maintenant je le vois 4 fois sur 5 je utiliser le programme.
Quelqu'un aurait-il des idées pour des solutions de contournement? La connexion bug indique que ce sera probablement corrigé dans la prochaine .NET version (à chaque fois que c'est) mais ce bug est de faire de notre application en fait inutilisable maintenant.
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:
Nous avons également essayé de simplement supprimer tout InvalidOperationException
s jetées à l'intérieur de notre ViewModel de la classe de base de l'événement PropertyChanged. Qui semblait réduire le nombre d'exceptions un peu, mais maintenant nous frapper juste en ObservableCollection
s' CollectionChanged
événement.