我有一个项目会抛出一些数据绑定错误。一个例子是:
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')
我的问题是,是否有办法确定实际声明此绑定的位置(在XAML或代码中声明)。
到目前为止我尝试过:
HorizontalContentAlignment
的所有绑定表达式;我发现只有一个并删除了它,但我仍然收到的信息似乎表明那不是错误的...... 您是否知道有任何其他技巧可以让WPF吐出一些更有用的信息,说明这个绑定的确切位置?
更新
经过一点点搜索后,我很确定这是由某种风格应用于MenuItem
造成的。但是,我仍然无法确定声明错误绑定的位置..
更新2
我发现了问题。然而问题仍然存在,因为发现问题主要是基于错误消息中的有限信息在黑暗中搜索。
事实证明,绑定是以样式声明的。风格不在我的应用程序中。它可能是MenuItem
的默认样式。因此,要解决此问题,我只需在所有HorizontalContentAlignment
上手动设置MenuItems
即可。错误的原因在某种程度上与操作顺序有关,因为在代码中生成了MenuItem
。我将单独发布一个新问题。
所以,就目前而言,故事的寓意是我觉得需要有一个更好的机制来确定声明错误绑定的位置。我希望看到类似于绑定的堆栈跟踪......
如果有人知道确定在代码或标记中声明绑定的位置的任何其他工具或方法,我会将问题保持打开一段时间。
我发布了另一个question regarding the style/binding being applied to the MenuItems
here。
答案 0 :(得分:90)
调试WPF绑定错误时,我发现用分号分解错误最简单,从最后开始
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')
从最后开始:
#5告诉您哪个属性包含失败的绑定。在您的情况下,它是HorizontalContentAlignment
#4是包含失败属性的元素,MenuItem
没有Name
属性来识别
所以某处有一个导致绑定错误的<MenuItem HorizontalContentAlignment="{Binding ...}" />
。
#3是目标元素后面的DataItem
或DataContext
。它似乎是null
,但这不是问题,因为它看起来你的绑定没有引用DataContext。
但这确实表明MenuItem
不属于常规VisualTree
,因为DataContext
通常是从父对象继承的。
#2包含实际的绑定错误和有关绑定的信息。它实际上可以进一步分解为多个部分。
Cannot find source for binding
with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''.
BindingExpression:Path=HorizontalContentAlignment;
“找不到源”意味着绑定找不到要绑定的源对象,在您的情况下,该源对象应该是{RelativeSource AncestorType={x:Type ItemsControl}
(FindAncestor
和AncestorLevel=1
是RelativeSource
的默认值,所以我忽略了那些)
#2的最后一部分显示了您要绑定的Path
:HorizontalContentAlignment
所以要把它们放在一起,代码中的某个地方有一个<MenuItem>
试图将其HorizontalContentAlignment
绑定到ItemsControl.HorizontalContentAlignment
,但绑定无法找到{ {1}}。
您正在使用ItemsControl
绑定来查找RelativeSource FindAncestor
,它会搜索可视树以查找最接近的ItemsControl
,并且找不到ItemsControl
,因此必须没有ItemsControl
{1}}来自MenuItem
的VisualTree层次结构中的更高层。
我经常会在ContextMenus
中看到此问题,因为它们不属于与其他XAML代码相同的VisualTree
。 (要引用附加VisualTree
的主ContextMenu
中的对象,您可以使用PlacementTarget
属性,例如this example。
一旦理解了绑定错误,通常很容易在XAML中找到它的来源。
根据我的应用程序大小,我通常会执行以下操作之一:
从绑定错误(在您的情况下为MenuItem
)中搜索应用程序中的“目标元素”,并查看是否有任何设置“目标属性”(HorizontalContentAlignment
)具有约束力
从绑定错误(HorizontalContentAlignment
)中搜索应用程序中的“目标属性”,以找到导致此问题的绑定
从绑定错误中显示的绑定文本中搜索应用程序中相当独特的内容。在您的情况下,您可以尝试搜索{x:Type ItemsControl}
RelativeSource
绑定中的一部分,并且搜索结果的搜索结果不应太多。
使用Snoop或WPF Inspector等第三方工具在运行时跟踪绑定错误。
我之前只使用过Snoop,但要使用它,你需要启动你的应用程序并对它运行Snoop来检查你的应用程序的VisualTree在运行时。然后,您可以通过在搜索栏中键入类似“MenuItem”的内容来搜索VisualTree,以过滤所有MenuItems
的可视树,然后查看其属性以找出哪个具有绑定错误({{1}由于绑定错误,属性将以红色突出显示)。
应该注意的是,如果您的HorizontalContentAlignment
位于MenuItem
内,那么您需要打开ContextMenu
以便绘制MenuItem并显示在Snoop中。
答案 1 :(得分:4)
也许您可以使用名为Snoop的优秀应用程序。这是免费的CodePlex。它帮助我找到了几个Binding问题,并且错过了数据上下文。它让我们探索整个WPF Visual树,并为您提供绑定错误。
Hope Snoop可以提供帮助。
答案 2 :(得分:1)
我是WPF的新手,我有完全相同的错误。虽然我现在已经修好了,但我真的不知道......以下是我尝试过的步骤:
首先,我有:
<Menu>
<ContextMenu>
中定义的<ListBox.ItemTemplate>
醇>
我试过:
<ContextMenu>
移至<ListBox.ItemContainerStyle>
- &gt;存在错误HorizontalContentAlignment
,VerticalContentAlignment
,<Menu>
- &gt;存在错误<ContextMenu>
和<MenuItem>
Name
- &gt;中为<MenuItem>
的{{1}}设置<ContextMenu>
属性没有错误! <ListBox.ItemTemplate>
属性 - &gt; 仍然没有错误...... 最终,我有
Name
<Menu>
<ContextMenu>
<ListBox.ItemTemplate>
<ContextMenu>
醇>
并且其中没有人设置了样式<ListBox.ItemContainerStyle>
和HorizontalContentAlignment
。错误已经消失......
似乎有一些刷新问题。因此,对于遇到相同问题的用户,您可以尝试重新启动VS或为VerticalContentAlignment
设置Name
属性...
答案 3 :(得分:-1)
System.Windows.Data错误:4 - 它不是你的问题,它是WPF知道的问题。它的项目动态更改的相关组合框/菜单。 See this。 顺便说一句,你可以忽略这些错误,通常应用程序工作正常。