Como algunos de ustedes han descubierto, apareció una nueva característica (?) WPF 4, donde el motor de enlace de datos puede pasar sus instancias de control personalizadas de la clase MS.Internal. NamedObject con el nombre "{DisconnectedItem}" en el DataContext, en lugar del elemento de datos que espera su código (esto ocurre cuando un control de plantilla está desconectado por ItemsControl). Estos se llaman objetos centinelas.Objetos WPF Sentinel y cómo buscar un tipo interno
En el código existente, esto puede dar lugar a excepciones falsas en las que el código no está preparado para ello. Estos pueden ser absorbidos por el subsistema de enlace de datos o pueden causar estragos. Vigila tu consola de depuración.
De todos modos, me enteré de esto en this MSDN forum. Y hay una publicación de Sam Bent que explains it all. Vaya a leerlo ahora, , querrá saber esto. La esencia es que estos eventos nunca debería haber disparado (que es el error), por lo que:
ignorar el evento DataContextChanged si la DataContext es un objeto de centinela.
Así que, entonces quiero verificar mi DataContext. ¿Pero cómo? Considere:
public bool IsSentinelObject(object dataContext)
{
return (dataContext is MS.Internal.NamedObject);
}
¿Adivina qué pasa? No se compila porque MS.Internal.NamedObject es interno y no es accesible para mí. Por supuesto, puedo entrar ilegalmente en él así:
public bool IsSentinelObject(object dataContext)
{
return dataContext.GetType().FullName == "MS.Internal.NamedObject"
|| dataContext.ToString() == "{DisconnectedObject}";
}
(o algo así, que trabaja). También he seguido la sugerencia de Sam de almacenar en caché el objeto para posteriores controles de igualdad de referencia (es un singleton).
Por supuesto, esto significa que no tengo un problema, realmente no. Pero tengo curiosidad, y esta publicación seguramente beneficiará a algunos usuarios, así que vale la pena preguntarlo de todos modos:
¿Hay alguna forma de que pueda verificar exactamente el tipo con el tipo de NamedObject interno, sin recurrir a comparaciones de cadenas?
'DataContextChanged' [ya no se produce en .NET 4.5. cuando se aprobaría {DisconnectedObject}. (https://connect.microsoft.com/VisualStudio/feedback/details/619658/wpf-virtualized-control-disconnecteditem-reference-when-datacontext-switch). –
Todavía encuentro problemas similares en .NET 4.5 mientras enlazo 'DataContext' a un elemento interno del DataContext (vea la composición del modelo). La solución consistía simplemente en evitar hacer esto y en lugar de actualizar todas las rutas de enlace a 'InnerElement. [Whathever]'. –