有没有办法确定声明/创建WPF绑定的位置?

时间:2013-01-24 21:15:29

标签: wpf data-binding

我有一个项目会抛出一些数据绑定错误。一个例子是:

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或代码中声明)。

到目前为止我尝试过:

  • 为System.Windows.Data命名空间添加了一个调试跟踪,其级别设置为全部;这没有产生更多有用的信息
  • 尝试在项目中对 Binding 进行文本搜索,希望找到路径设置为HorizontalContentAlignment的所有绑定表达式;我发现只有一个并删除了它,但我仍然收到的信息似乎表明那不是错误的......

您是否知道有任何其他技巧可以让WPF吐出一些更有用的信息,说明这个绑定的确切位置?

更新

经过一点点搜索后,我很确定这是由某种风格应用于MenuItem造成的。但是,我仍然无法确定声明错误绑定的位置..

更新2

我发现了问题。然而问题仍然存在,因为发现问题主要是基于错误消息中的有限信息在黑暗中搜索。

事实证明,绑定是以样式声明的。风格不在我的应用程序中。它可能是MenuItem的默认样式。因此,要解决此问题,我只需在所有HorizontalContentAlignment上手动设置MenuItems即可。错误的原因在某种程度上与操作顺序有关,因为在代码中生成了MenuItem。我将单独发布一个新问题。

所以,就目前而言,故事的寓意是我觉得需要有一个更好的机制来确定声明错误绑定的位置。我希望看到类似于绑定的堆栈跟踪......

如果有人知道确定在代码或标记中声明绑定的位置的任何其他工具或方法,我会将问题保持打开一段时间。

我发布了另一个question regarding the style/binding being applied to the MenuItems here

4 个答案:

答案 0 :(得分:90)

调试WPF绑定错误时,我发现用分号分解错误最简单,从最后开始

  1. System.Windows.Data Error: 4 :
  2. Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. BindingExpression:Path=HorizontalContentAlignment;
  3. DataItem=null;
  4. target element is 'MenuItem' (Name='');
  5. target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment')
  6. 从最后开始:

    • #5告诉您哪个属性包含失败的绑定。在您的情况下,它是HorizontalContentAlignment

    • #4是包含失败属性的元素,MenuItem没有Name属性来识别

      所以某处有一个导致绑定错误的<MenuItem HorizontalContentAlignment="{Binding ...}" />

    • #3是目标元素后面的DataItemDataContext。它似乎是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}FindAncestorAncestorLevel=1RelativeSource的默认值,所以我忽略了那些)

      #2的最后一部分显示了您要绑定的PathHorizontalContentAlignment

    所以要把它们放在一起,代码中的某个地方有一个<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绑定中的一部分,并且搜索结果的搜索结果不应太多。

    • 使用SnoopWPF 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的新手,我有完全相同的错误。虽然我现在已经修好了,但我真的不知道......以下是我尝试过的步骤:

首先,我有:

  1. a <Menu>
  2. <ContextMenu> 中定义的
  3. 2 <ListBox.ItemTemplate>

    我试过:

    1. <ContextMenu>移至<ListBox.ItemContainerStyle> - &gt;存在错误
    2. HorizontalContentAlignmentVerticalContentAlignment<Menu> - &gt;存在错误
    3. 设置并删除样式<ContextMenu><MenuItem>
    4. Name - &gt;中为<MenuItem>的{​​{1}}设置<ContextMenu>属性没有错误!
    5. 删除<ListBox.ItemTemplate>属性 - &gt; 仍然没有错误......
    6. 重启VS - &gt; 错误似乎永远消失了......
    7. 最终,我有

      1. a Name
      2. <Menu>
      3. 中定义的<ContextMenu>
      4. <ListBox.ItemTemplate>
      5. 中定义的<ContextMenu>

        并且其中没有人设置了样式<ListBox.ItemContainerStyle>HorizontalContentAlignment。错误已经消失......

        似乎有一些刷新问题。因此,对于遇到相同问题的用户,您可以尝试重新启动VS或为VerticalContentAlignment设置Name属性...

答案 3 :(得分:-1)

System.Windows.Data错误:4 - 它不是你的问题,它是WPF知道的问题。它的项目动态更改的相关组合框/菜单。 See this。 顺便说一句,你可以忽略这些错误,通常应用程序工作正常。