저는 최근에 정말 나쁜 WPF 버그를 쳤습니다. Microsoft Connect의 this bug과 같다고 생각합니다. 의 ViewModel가 ItemsControl에에서 이동하는 항목을 일으키는 모든 속성 또는 컬렉션에 변화를 트리거 할 때 2010 년WPF Freezable 버그에 대한 대안?
기본적으로 비주얼 스튜디오를 사용하여
우리의 응용 프로그램을 대상으로 .NET 4.0 클라이언트 프로파일은 예외가 그 기회있다 아래에 던져 질 것입니다. 항상 발생하는 것은 아니며 다른시기에 따라 다른 것으로 나타날 수 있습니다. 신청을 시작한 직후에 더 많은 것으로 보입니다. 예외를 두지 않고 몇 분 동안 사용할 수 있다면 아마 그 응용 프로그램 인스턴스 중에 결코 적중하지 않을 것입니다.
Connect 버그 보고서와 마찬가지로 을 사용하여 ResourceDictionary
에서 SolidColorBrush
을로드합니다. 사전 중 일부는 수동으로로드됩니다 (지원 대상). 나는 그 사전에있는 모든 것을 수동으로 동결 시키려고했지만, 도움이되지는 않았다.
ObservableCollection
에 바인드 된 ItemsControls가있는 기본 창에 두 개 이상의 UserControl
을 추가 할 때 예외가 최근에 많이 발생했습니다. 이전에는 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 .....
편집 : 우리는 단순히 우리의 뷰 모델의 기본 클래스의하여 PropertyChanged 이벤트의 내부에 던져 어떤 InvalidOperationException
의 억제 시도했습니다. 이는 예외 수를 다소 줄이는 것처럼 보였지만 이제는 ObservableCollection
의 CollectionChanged
이벤트에 도달했습니다.
Dispatcher.Invoke를 사용하여 다른 우선 순위로 코드에서 OnPropertyChanged를 발생 시키려고 했습니까? 때로는 영향을주기 위해 사용하는 것입니다 - 조금은 무작위로 동의합니다 :-) 경쟁 조건에 대한 WPF ... –
야생 추측이지만 인스턴스 생성시 사전에 참조 된 브러시 리소스를 모두 고정 할 수 있습니까? 여기에서하는 방법을 읽을 수 있습니다 : http://stackoverflow.com/questions/799890/how-can-wpf-objects-deriving-from-freezable-be-frozen-in-xaml –
또한, UI 스레드에서 ObservableCollection 만 수정하면됩니까? –