J'ai un projet qui génère des erreurs de liaison de données. Un exemple est:
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')
Ma question est de savoir s'il existe un moyen de déterminer où cette liaison est réellement déclarée (ou elle est déclarée en XAML ou en code).
Ce que j'ai essayé jusqu'à présent:
HorizontalContentAlignment
name__; Je n’en ai trouvé qu’un et l’ai enlevé, mais je reçois toujours le message qui semble indiquer que ce n’était pas le défaut.Connaissez-vous d'autres astuces pour faire en sorte que WPF publie des informations plus utiles sur l'emplacement exact où cette liaison est déclarée?
METTRE À JOUR
Après un peu plus de recherches, je suis presque certain que cela est dû à un style appliqué à un MenuItem
name__. Cependant, je ne suis toujours pas en mesure de localiser l'emplacement où la liaison défectueuse est déclarée.
UPDATE 2
J'ai trouvé le problème. Cependant, la question demeure, car trouver le problème consistait principalement à effectuer une recherche dans le noir sur la base des informations limitées contenues dans le message d'erreur.
Il s'avère que la liaison est déclarée dans un style. Et le style n'est pas dans mon application. C'est probablement le style par défaut pour MenuItem
name__. Donc, pour résoudre le problème pour le moment, je viens de définir manuellement le HorizontalContentAlignment
sur tous les MenuItems
name__. La raison de l'erreur est liée à l'ordre des opérations car ce MenuItem
est généré dans le code. Je posterai une nouvelle question à ce sujet séparément.
Donc, pour l’instant, la morale de l’histoire est que j’estime qu’il faut un meilleur mécanisme pour déterminer où la reliure défectueuse est déclarée. Je voudrais voir quelque chose comme une trace de pile pour les liaisons ..
Je laisse la question ouverte un peu plus longtemps au cas où quelqu'un aurait connaissance d'autres outils ou méthodes permettant de déterminer le lieu où une liaison est déclarée dans le code ou le balisage.
J'ai posté une autre question concernant le style/la liaison appliquée à MenuItems
here .
Lors du débogage des erreurs de liaison WPF, il est plus facile de séparer l'erreur par des points-virgules et de commencer à la fin.
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')
Donc à partir de la fin:
N ° 5 vous indique quelle propriété contient la liaison qui échoue. Dans votre cas, c'est HorizontalContentAlignment
# 4 est l'élément contenant la propriété en échec, qui est une MenuItem
sans une Name
pour l'identifier par
Donc, quelque part, vous avez un <MenuItem HorizontalContentAlignment="{Binding ...}" />
qui est à l'origine de l'erreur de liaison.
# 3 est la DataItem
ou DataContext
qui se trouve derrière l'élément cible. Il semble être null
pour vous, mais ce n'est pas un problème car il semble que votre liaison ne fait pas référence à DataContext.
Mais cela suggère que la MenuItem
ne fait pas partie de votre VisualTree
ordinaire, car typiquement la DataContext
est héritée de l'objet parent.
# 2 contient l'erreur de liaison réelle et des informations sur la liaison. Il peut en réalité être divisé en plusieurs parties.
Cannot find source for binding
with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''.
BindingExpression:Path=HorizontalContentAlignment;
"Impossible de trouver la source" signifie que la liaison ne peut pas trouver l'objet source auquel se lier, et dans votre cas, cet objet source doit être {RelativeSource AncestorType={x:Type ItemsControl}
(FindAncestor
et AncestorLevel=1
sont les valeurs par défaut pour une RelativeSource
, je les ignore donc)
Et la dernière partie de # 2 montre la Path
à laquelle vous essayez de vous lier: HorizontalContentAlignment
Donc pour résumer, quelque part dans votre code, il y a un <MenuItem>
qui tente de lier sa HorizontalContentAlignment
à un ItemsControl.HorizontalContentAlignment
, mais la liaison ne trouve pas la ItemsControl
.
Vous utilisez une liaison RelativeSource FindAncestor
pour rechercher la variable ItemsControl
, qui effectue une recherche dans l'arbre visuel pour rechercher la variable ItemsControl
la plus proche. Elle ne la trouve pas. Il ne doit donc pas y avoir de ItemsControl
dans la hiérarchie VisualTree à partir de la variable MenuItem
.
Je vois souvent ce problème avec ContextMenus
car ils ne font pas partie de la même VisualTree
que le reste de votre code XAML. (Pour référencer l'objet dans la variable VisualTree
principale à laquelle une variable ContextMenu
est attachée, vous pouvez utiliser la propriété PlacementTarget
, comme cet exemple .
Une fois que vous avez compris l’erreur de liaison, il est souvent facile de trouver la source de celle-ci dans votre XAML.
En fonction de la taille de mon application, je fais généralement l'une des choses suivantes:
Recherchez dans "l'application" l'élément "de l'erreur de liaison (dans votre cas, MenuItem
) et voyez si l'un d'entre eux définit la" propriété cible "(HorizontalContentAlignment
) avec une liaison.
Recherchez dans l'application la "propriété cible" de l'erreur de liaison (HorizontalContentAlignment
) pour rechercher la liaison à l'origine de ce problème.
Recherchez dans l'application quelque chose d'assez unique parmi le texte de liaison indiqué dans l'erreur de liaison. Dans votre cas, vous pouvez essayer de rechercher sur {x:Type ItemsControl}
qui ferait partie de votre liaison RelativeSource
et il ne devrait pas y avoir trop de résultats de recherche pour une telle phrase.
Utilisez un outil tiers tel que Snoop ou WPF Inspector pour localiser l'erreur de liaison au moment de l'exécution.
Je n'avais auparavant utilisé que Snoop, mais pour l'utiliser, vous devez démarrer votre application et l'exécuter pour l'examiner afin d'inspecter VisualTree de votre application pendant son exécution. Vous pouvez ensuite effectuer une recherche dans VisualTree en tapant quelque chose comme "MenuItem" dans la barre de recherche pour filtrer l’arborescence visuelle de toutes les MenuItems
, puis parcourez leurs propriétés pour trouver celle qui présente une erreur de liaison (la propriété HorizontalContentAlignment
sera surlignée en rouge car de l'erreur de liaison).
Il est à noter que si votre MenuItem
est dans une ContextMenu
, vous devez alors ouvrir cette ContextMenu
pour que les éléments de menu soient dessinés et affichés dans Snoop.
Peut-être que vous pourriez utiliser cette excellente application nommée Snoop . C'est gratuit dans CodePlex . Cela m'aide à trouver plusieurs problèmes de liaison et les contextes de données manquantes. Il permet d’explorer l’ensemble de l’arborescence visuelle WPF et de vous donner les erreurs de liaison.
Hope Snoop pourrait vous aider.
Je suis nouveau sur WPF et j'ai exactement la même erreur. Bien que je l'ait corrigé maintenant, je ne sais vraiment pas comment ... Voici les étapes que j'ai essayées:
Tout d'abord, j'ai:
<Menu>
<ContextMenu>
défini dans <ListBox.ItemTemplate>
J'ai essayé de:
<ContextMenu>
dans <ListBox.ItemContainerStyle>
-> erreur existeHorizontalContentAlignment
et VerticalContentAlignment
pour <Menu>
, <ContextMenu>
, <MenuItem>
-> error existeName
pour le <MenuItem>
du <ContextMenu>
dans <ListBox.ItemTemplate>
-> aucune erreur! Name
-> toujours pas d'erreur ... Finalement, j'ai
<Menu>
<ContextMenu>
défini dans <ListBox.ItemTemplate>
<ContextMenu>
défini dans <ListBox.ItemContainerStyle>
et NONE d’eux n’ont défini le style HorizontalContentAlignment
et VerticalContentAlignment
. Et l'erreur est partie ...
On dirait qu'il y a un problème d'actualisation. Donc, pour ceux qui ont le même problème, vous pouvez essayer de redémarrer le VS ou définir l'attribut Name
pour le <MenuItem>
...