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

Mik*_*scu 32 data-binding 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')

我的问题是,是否有办法确定实际声明此绑定的位置(无论是在XAML中还是在代码中声明).

到目前为止我尝试过的:

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

你知道有什么其他的技巧可以让WPF吐出一些更有用的信息,说明这个绑定的确切位置在哪里?

UPDATE

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

更新2

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

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

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

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

我发布了另一个关于应用于MenuItems此处的样式/绑定的问题.

Rac*_*hel 96

在调试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')

所以从头到尾:

  • #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是a的默认值RelativeSource,所以我忽略了那些)

    #2的最后一部分显示了Path您要绑定到:HorizontalContentAlignment

所以把它们放在一起,在你的代码中的某个地方有一个<MenuItem>试图将它绑定HorizontalContentAlignment到一个ItemsControl.HorizontalContentAlignment,但绑定无法找到ItemsControl.

你正在使用一个RelativeSource FindAncestor绑定来查找ItemsControl,它搜索可视树以找到最接近的ItemsControl,并且找不到一个,所以ItemsControl在VisualTree层次结构中必须没有更高的值MenuItem.

我经常看到这个问题,ContextMenus因为它们与VisualTreeXAML代码的其余部分不同.(引用该对象在主VisualTree,一个ContextMenu附接到,则可以使用PlacementTarget属性,像本实施例中.

一旦理解了绑定错误,通常很容易在XAML中找到它的来源.

根据我的应用程序大小,我通常会执行以下操作之一:

  • 从绑定错误(在您的情况下MenuItem)中搜索应用程序中的"目标元素" ,并查看其中是否有任何HorizontalContentAlignment一个使用绑定设置"目标属性"()

  • 从绑定错误(HorizontalContentAlignment)中搜索应用程序中的"目标属性",以找到导致此问题的绑定

  • 从绑定错误中显示的绑定文本中搜索应用程序中相当独特的内容.在您的情况下,您可以尝试搜索{x:Type ItemsControl}哪些是RelativeSource绑定的一部分,并且搜索结果不应该太多这样的短语.

  • 使用第三方工具(如SnoopWPF Inspector)在运行时跟踪绑定错误.

    我之前只使用过Snoop,但要使用它,你需要启动你的应用程序并对它运行Snoop来检查你的应用程序的VisualTree在它运行时.然后,您可以通过在搜索栏中键入类似"MenuItem"的内容来搜索VisualTree,以便为所有人过滤Visual Tree MenuItems,然后查看其属性以找出哪一个具有绑定错误(该HorizontalContentAlignment属性将以红色突出显示,因为绑定错误).

    应该注意的是,如果你MenuItem在a里面ContextMenu,那么你需要打开它ContextMenu以便绘制MenuItem并显示在Snoop中.

  • 事实上,这个答案只有4个(现在是5个)投票,这是多年来SO如何变化的一个很好的例子.它已被观看超过1300次!为什么人们如此吝啬?Mods被诅咒,删除此评论,不要删除它,whatevs. (3认同)

Raú*_*año 4

也许您可以使用这个名为Snoop的优秀应用程序。它在CodePlex中是免费的。它帮助我找到几个绑定问题,以及丢失的数据上下文。它让您探索整个 WPF 可视化树,并为您提供绑定错误。

希望史努比能帮忙。