tutorial que español controles .net wpf .net-4.0 freezable

.net - que - xaml tutorial



¿Solución para el error Freezable de WPF? (3)

Cada vez que se trata de un comportamiento defectuoso en torno a MVVM con ItemsControl y los controles derivados, mi primer intento es deshabilitar VirtualizingStackPanel.

<ItemsControl VirtualizingStackPanel.IsVirtualizing="False" />

Sólo un intento ...

He estado golpeando un muy mal error WPF recientemente. Creo que es lo mismo que este error en Microsoft Connect.

Nuestra aplicación apunta al perfil de cliente .NET 4.0 mediante Visual Studio 2010.

Básicamente, cuando un ViewModel desencadena un cambio en cualquier propiedad o colección que hace que los elementos se muevan en un ItemsControl, existe la posibilidad de que se lance la excepción a continuación. No siempre sucede y parece suceder según diferentes desencadenantes en diferentes momentos. Parece ser más probable poco después de iniciar la aplicación. Si puede usarlo por un par de minutos sin golpear la excepción, probablemente nunca lo haga durante esa instancia de la aplicación.

Al igual que el informe de error de Connect, estoy usando {DynamicResource key} para cargar SolidColorBrush es desde un ResourceDictionary . Algunos de los diccionarios se cargan manualmente (para soporte de temas). Intenté congelar manualmente todo en esos diccionarios, pero no parece haber ayudado.

Las excepciones se han vuelto mucho más frecuentes últimamente cuando agregué un par de UserControl más a la ventana principal que tienen ItemsControls vinculados a ObservableCollection s. Anteriormente, solo veía la excepción 1 vez de 50, pero ahora la veo 4 de 5 veces que uso el programa.

¿Alguien tiene alguna idea para las soluciones? El error de conexión indica que esto probablemente se solucionará en la próxima versión de .NET (siempre que sea), pero este error hace que nuestra aplicación sea básicamente inutilizable ahora.

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 .....

EDITAR: También hemos intentado simplemente suprimir cualquier InvalidOperationException s lanzada dentro de nuestro evento PropertyChanged de la clase base ViewModel. Eso pareció reducir un poco el número de excepciones, pero ahora simplemente las ObservableCollection en el evento CollectionChanged ObservableCollection .


No creo que haya una solución para esto. Al tener que lidiar con esto yo mismo, por lo que he leído, WPF congela automáticamente los recursos en la creación. Por lo tanto, cada vez que intente utilizar un DynamicResource en ese recurso, obtendrá la excepción que se puede congelar.

Aquí hay una cita del equipo de Microsoft Foundation sobre lo que está sucediendo:

"WPF congelará los elementos que se pueden congelar dentro de un estilo o plantilla. Los estilos y las plantillas se pueden usar en varios subprocesos, y los elementos que se pueden congelar no se pueden congelar. Actualmente estamos considerando extender esto a cualquier cosa dentro de los Recursos de la Aplicación. tiene el mismo problema de subprocesamiento ... DynamicResource en un congelador congelado no funciona, porque un congelable congelado potencialmente tiene varios padres, por lo que es ambiguo a qué padre buscaríamos el recurso ".


Para solucionar este error .net, cambie todos los pinceles de color sólido en su código para que puedan congelarse. Por ejemplo

<SolidColorBrush x:Key="WindowBackground" Color="Black" />

debe cambiarse a:

<SolidColorBrush po:Freeze="True" x:Key="WindowBackground" Color="Black" />.

Para obtener instrucciones más detalladas, consulte aquí: ¿Cómo se pueden congelar los objetos WPF derivados de Freezable en XAML? .