two - ¿Hay alguna forma de determinar dónde se declara/crea un enlace WPF?
wpf binding types (4)
Al depurar errores de enlace WPF, me resulta más fácil dividir el error por el punto y coma, y comenzar desde el final
-
System.Windows.Data Error: 4 :
-
Cannot find source for binding with reference ''RelativeSource FindAncestor, AncestorType=''System.Windows.Controls.ItemsControl'', AncestorLevel=''1''''. BindingExpression:Path=HorizontalContentAlignment;
-
DataItem=null;
-
target element is ''MenuItem'' (Name='''');
-
target property is ''HorizontalContentAlignment'' (type ''HorizontalAlignment'')
Así que comenzando desde el final:
# 5 le dice qué propiedad contiene el enlace que está fallando. En tu caso, es
HorizontalContentAlignment
# 4 es el elemento que contiene la propiedad anómala, que es un elemento
MenuItem
sinName
para identificarlo porEntonces, en algún lugar, tiene un
<MenuItem HorizontalContentAlignment="{Binding ...}" />
que está causando el error de enlace.# 3 es el
DataItem
, oDataContext
, que está detrás del elemento objetivo. Parece sernull
para usted, pero eso no es un problema, ya que parece que su enlace no está haciendo referencia al DataContext.Pero esto sugiere que
MenuItem
no es parte de suVisualTree
regular, ya que normalmente elDataContext
se hereda del objeto principal.# 2 contiene el error de enlace real y la información sobre el enlace. En realidad, se puede dividir en varias partes.
Cannot find source for binding
with reference ''RelativeSource FindAncestor, AncestorType=''System.Windows.Controls.ItemsControl'', AncestorLevel=''1''''.
BindingExpression:Path=HorizontalContentAlignment;
"No se puede encontrar la fuente" significa que el enlace no puede encontrar el objeto de origen al cual vincularse, y en su caso, ese objeto fuente debe ser
{RelativeSource AncestorType={x:Type ItemsControl}
(FindAncestor
yAncestorLevel=1
son valores predeterminados paraRelativeSource
, entonces estoy ignorando esos)Y la última parte del # 2 muestra la
Path
que intentas vincular:HorizontalContentAlignment
Entonces, para poner todo junto, en algún lugar de su código hay un <MenuItem>
que está tratando de vincular su HorizontalContentAlignment
con un ItemsControl.HorizontalContentAlignment
, pero el enlace no puede encontrar ItemsControl
.
Está utilizando un enlace RelativeSource FindAncestor
para encontrar ItemsControl
, que busca el árbol visual para encontrar el ItemsControl
más ItemsControl
, y no lo encuentra, por lo que no debe haber ItemsControl
más arriba en la jerarquía de VisualTree desde MenuItem
.
A menudo veo este problema con ContextMenus
porque no son parte del mismo VisualTree
que el resto de tu código XAML. (Para hacer referencia al objeto en el VisualTree
principal VisualTree
que está conectado un ContextMenu
, puede usar la propiedad PlacementTarget
, como en este ejemplo .
Una vez que comprenda el error de enlace, a menudo es fácil encontrar su origen en su XAML.
Dependiendo del tamaño de mi aplicación, generalmente hago uno de los siguientes:
Busque en la aplicación el "elemento de destino" del error de enlace (en su caso,
MenuItem
), y vea si alguno de ellos está configurando la "propiedad de destino" (HorizontalContentAlignment
) con un enlaceBusque en la aplicación la "propiedad de destino" del error de enlace (
HorizontalContentAlignment
) para encontrar el enlace que causa este problemaBusque en la aplicación algo bastante único del texto vinculante que se muestra en el error de enlace. En su caso, podría intentar buscar en
{x:Type ItemsControl}
que sería parte de su enlaceRelativeSource
, y no debería haber demasiados resultados de búsqueda para dicha frase.Utilice una herramienta de terceros como Snoop o WPF Inspector para rastrear el error de vinculación en tiempo de ejecución.
Solo he usado Snoop anteriormente, pero para usarlo necesitas iniciar tu aplicación y ejecutar Snoop contra ella para inspeccionar el VisualTree de tu aplicación mientras se está ejecutando. Luego puede buscar en el VisualTree escribiendo algo como "MenuItem" en la barra de búsqueda para filtrar el Árbol visual para todos los elementos del
MenuItems
, luego revise sus propiedades para descubrir cuál tiene un error de encuadernación (la propiedadHorizontalContentAlignment
se resaltará en rojo porque del error de enlace).Cabe señalar que si tu elemento de
MenuItem
está dentro de unContextMenu
, entonces necesitas abrir eseContextMenu
para que los artículos del menú se dibujen y aparezcan en Snoop.
Tengo un proyecto que arroja algunos errores de enlace de datos. Un ejemplo es:
System.Windows.Data Error: 4 : Cannot find source for binding with reference ''RelativeSource FindAncestor, AncestorType=''System.Windows.Controls.ItemsControl'', AncestorLevel=''1''''. BindingExpression:Path=HorizontalContentAlignment; DataItem=null; target element is ''MenuItem'' (Name=''''); target property is ''HorizontalContentAlignment'' (type ''HorizontalAlignment'')
Mi pregunta es si hay una forma de determinar dónde se declara realmente este enlace (ya sea que esté declarado en XAML o en código).
Lo que he intentado hasta ahora:
- agregó un seguimiento de depuración para el espacio de nombres System.Windows.Data con nivel establecido o Todos; esto no produjo más información útil
- intenté hacer una búsqueda de texto en el proyecto de la palabra Vinculando con la esperanza de localizar todas las expresiones vinculantes que tengan la Ruta establecida en
HorizontalContentAlignment
; Encontré solo uno y lo eliminé, pero sigo recibiendo el mensaje que parece indicar que ese no era el error.
¿Conoce algún otro truco para que WPF escuche información más útil sobre dónde se declara exactamente este enlace?
ACTUALIZAR
Después de buscar un poco más, estoy bastante seguro de que esto de alguna manera es causado por un estilo que se aplica a un MenuItem
. Sin embargo, todavía no puedo identificar la ubicación donde se declara el enlace defectuoso.
ACTUALIZACIÓN 2
Encontré el problema. Sin embargo, la pregunta aún permanece, ya que encontrar el problema fue principalmente una cuestión de búsqueda en la oscuridad en función de la información limitada en el mensaje de error.
Como resultado, el enlace se declara en un estilo. Y el estilo no está en mi aplicación. Probablemente sea el estilo predeterminado para MenuItem
. Así que, para solucionar el problema por ahora, he establecido manualmente HorizontalContentAlignment
en todos los artículos del MenuItems
. La razón del error está de alguna manera relacionada con el orden de las operaciones ya que este elemento del MenuItem
se genera en el código. Voy a publicar una nueva pregunta sobre eso por separado.
Entonces, por ahora, la moraleja de la historia es que siento que debe haber un mecanismo mejor para determinar dónde se declara el enlace defectuoso. Me gustaría ver algo así como un rastro de pila para enlaces.
Mantendré la pregunta abierta por un tiempo más largo en caso de que alguien sepa de otras herramientas o métodos para determinar el lugar donde se declara un enlace en el código o el marcado.
He publicado otra pregunta sobre el estilo / enlace que se aplica a MenuItems
aquí .
Error de System.Windows.Data: 4 - no es su problema, es un problema conocido de WPF. Se trata de cuadros combinados / menús cuyos elementos se cambian dinámicamente. Mira esto Por cierto, puede ignorar estos errores, por lo general la aplicación funciona bien.
Soy nuevo en WPF y tengo exactamente el mismo error. Aunque lo he solucionado ahora, realmente no sé cómo ... a continuación se muestran los pasos que he intentado:
Primero que nada, tengo:
- un
<Menu>
- 2
<ContextMenu>
definido en<ListBox.ItemTemplate>
He intentado:
- mover un
<ContextMenu>
en<ListBox.ItemContainerStyle>
- existe un error - Establezca y elimine el estilo
HorizontalContentAlignment
yVerticalContentAlignment
para<Menu>
,<ContextMenu>
,<MenuItem>
-> existe un error - Establezca el atributo
Name
para<MenuItem>
de<ContextMenu>
en<ListBox.ItemTemplate>
-> ¡ sin error! - Elimina el atributo
Name
-> sigue sin error ... - Reinicia el VS -> el error parece haber desaparecido para siempre ...
Eventualmente, tengo
- un
<Menu>
- a
<ContextMenu>
definido en<ListBox.ItemTemplate>
- a
<ContextMenu>
definido en<ListBox.ItemContainerStyle>
y NINGUNO de ellos ha establecido el estilo HorizontalContentAlignment
y VerticalContentAlignment
. Y el error se ha ido ...
Parece que hay algún problema de actualización. Entonces, para aquellos que tienen el mismo problema, podrían intentar reiniciar el VS o establecer el atributo Name
para el <MenuItem>
...