有没有办法确定 WPF 绑定的声明/创建位置?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14510931/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a way to determine where a WPF Binding is declared/created?
提问by Mike Dinescu
I have a project which is throwing some data binding errors. One example is:
我有一个项目抛出一些数据绑定错误。一个例子是:
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')
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')
My question is whether there is a way to determine where this binding is actually declared (either it is declared in XAML or in code).
我的问题是是否有办法确定此绑定的实际声明位置(在 XAML 或代码中声明)。
What I've tried so far:
到目前为止我尝试过的:
- added a debug trace for the System.Windows.Data namespace with level set o All; this did not produce any more useful information
- tried doing a text-search in the project for the word Bindingin hopes of locating all binding expressions that have the Path set to
HorizontalContentAlignment; I found only one and removed it but I'm still getting the message which seems to indicate that that was not the faulty one..
- 为 System.Windows.Data 命名空间添加了调试跟踪,级别设置为 o All;这并没有产生更多有用的信息
- 尝试在项目中对Binding一词进行文本搜索,希望找到所有将 Path 设置为 的绑定表达式
HorizontalContentAlignment;我只找到了一个并删除了它,但我仍然收到消息,这似乎表明那不是错误的。
Do you know of any other tricks to make WPF spit out some more useful information about where exactly is this binding declared?
你知道有什么其他技巧可以让 WPF 吐出一些关于这个绑定到底在哪里声明的更有用的信息吗?
UPDATE
更新
After a little bit more searching I'm pretty sure this is somehow caused by a style being applied to a MenuItem. However, I'm still not able to pin-point the location where the faulty binding is being declared..
经过更多的搜索,我很确定这是由于某种样式应用于MenuItem. 但是,我仍然无法确定声明错误绑定的位置。
UPDATE 2
更新 2
I found the problem. However the question still remains since finding the issue was mostly a matter of searching in the dark based on the limited info in the error message.
我发现了问题。然而,问题仍然存在,因为发现问题主要是基于错误消息中的有限信息在黑暗中进行搜索。
As it turns out, the binding is declared in a style. And the style is not in my application. It's probably the default style for MenuItem. So to fix the issue for now I've just manually set the HorizontalContentAlignmenton all MenuItems. The reason for the error is somehow related to order of operations as this MenuItemis generated in code. I'll post a new question on that separately.
事实证明,绑定是在样式中声明的。而且样式不在我的应用程序中。这可能是MenuItem. 所以现在为了解决这个问题,我只是手动设置了HorizontalContentAlignment所有MenuItems. 错误的原因在某种程度上与操作顺序有关,因为这MenuItem是在代码中生成的。我将单独发布一个新问题。
So, for now, the moral of the story is that I feel that there needs to be a better mechanism to determine where the faulty binding is declared. I'd like to see something like a stack trace for bindings..
所以,就目前而言,这个故事的寓意是我觉得需要一个更好的机制来确定在哪里声明了错误的绑定。我想看到类似绑定的堆栈跟踪的东西..
I'm keeping the question open for a little while longer in case somebody knows of any other tools or methods of determining the place where a binding is declared in code or markup.
如果有人知道任何其他工具或方法来确定在代码或标记中声明绑定的位置,我会将这个问题保留一段时间。
I've posted another question regarding the style/binding being applied to the MenuItemshere.
我已经发布了另一个关于应用于MenuItemshere的样式/绑定的问题。
回答by Rachel
When debugging WPF binding errors, I find it easiest to break up the error by the semicolons, and start from the end
在调试 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')
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')
So starting from the end:
所以从最后开始:
#5 tells you what property contains the binding that is failing. In your case, it's
HorizontalContentAlignment#4 is the element containing the failing property, which is a
MenuItemwithout aNameproperty to identify it bySo somewhere you have a
<MenuItem HorizontalContentAlignment="{Binding ...}" />that is causing the binding error.#3 is the
DataItem, orDataContext, that is behind the target element. It appears to benullfor you, but that's not a problem since it looks like your binding isn't referencing the DataContext.But this does suggest that the
MenuItemis not part of your regularVisualTree, since typically theDataContextis inherited from the parent object.#2 contains the actual binding error and information about the binding. It can actually be further broken up into multiple parts.
Cannot find source for bindingwith reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''.BindingExpression:Path=HorizontalContentAlignment;
"Cannot find source" means the binding can't find the source object to bind to, and in your case, that source object should be
{RelativeSource AncestorType={x:Type ItemsControl}(FindAncestorandAncestorLevel=1are defaults for aRelativeSource, so I'm ignoring those)And the last part of #2 shows the
Pathyou are trying to bind to:HorizontalContentAlignment
#5 告诉您哪个属性包含失败的绑定。在你的情况下,它是
HorizontalContentAlignment#4 是包含失败属性的元素,这是一个
MenuItem没有Name属性来识别它的元素所以在某处你有一个
<MenuItem HorizontalContentAlignment="{Binding ...}" />导致绑定错误的地方。#3 是目标元素后面的
DataItem, orDataContext。它似乎null适合您,但这不是问题,因为您的绑定似乎没有引用 DataContext。但这确实表明
MenuItem不是您的常规 的一部分VisualTree,因为通常DataContext是从父对象继承的。#2 包含实际绑定错误和有关绑定的信息。它实际上可以进一步分解为多个部分。
Cannot find source for bindingwith 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
So to put it all together, somewhere in your code there is a <MenuItem>which is trying to bind its HorizontalContentAlignmentto an ItemsControl.HorizontalContentAlignment, but the binding can't find the ItemsControl.
所以把它们放在一起,在你的代码中的某个地方有一个<MenuItem>试图将它的绑定HorizontalContentAlignment到一个ItemsControl.HorizontalContentAlignment,但绑定找不到ItemsControl.
You're using a RelativeSource FindAncestorbinding to find the ItemsControl, which searches up the visual tree to find the closest ItemsControl, and it's not finding one so there must be no ItemsControlhigher up in the VisualTree hierarchy from the MenuItem.
您正在使用RelativeSource FindAncestor绑定来查找ItemsControl,它搜索可视化树以找到最接近的ItemsControl,但它没有找到,因此ItemsControl在 VisualTree 层次结构中必须没有比MenuItem.
I often see this problem with ContextMenusbecause they are not part of the same VisualTreeas the rest of your XAML code. (To reference the object in the main VisualTreethat a ContextMenuis attached to, you can use the PlacementTargetproperty, like this example.
我经常看到这个问题,ContextMenus因为它们与VisualTreeXAML 代码的其余部分不同。(要引用VisualTreeaContextMenu附加到的主对象中的对象,您可以使用该PlacementTarget属性,例如本例。
Once you understand the binding error, its often easy to find the source of it in your XAML.
一旦您了解绑定错误,通常很容易在您的 XAML 中找到它的来源。
Depending on my application size, I usually do one of the following:
根据我的应用程序大小,我通常会执行以下操作之一:
Search the application for the "target element" from the binding error (in your case,
MenuItem), and see if any of them are setting the "target property" (HorizontalContentAlignment) with a bindingSearch the application for the "target property" from the binding error (
HorizontalContentAlignment) to find the binding causing this problemSearch the application for something fairly unique from the binding text shown in the binding error. In your case, you could try searching on
{x:Type ItemsControl}which would be part of yourRelativeSourcebinding, and there shouldn't be too many search results for such a phrase.Use a 3rd party tool like Snoopor WPF Inspectorto track down the binding error at run time.
I've only used Snoop before, but to use it you need to startup your application and run Snoop against it to inspect your application's VisualTree while it's running. You can then search the VisualTree by typing something like "MenuItem" in the search bar to filter the Visual Tree for all
MenuItems, then look through their properties to find out which one has a binding error (theHorizontalContentAlignmentproperty will be highlighted in red because of the binding error).It should be noted that if if your
MenuItemis inside aContextMenu, then you need to open thatContextMenufor the MenuItems to be drawn and show up in Snoop.
从绑定错误中搜索“目标元素”的应用程序(在您的情况下,
MenuItem),并查看其中是否有任何人正在HorizontalContentAlignment使用绑定设置“目标属性”()在应用程序中从绑定错误 (
HorizontalContentAlignment) 中搜索“目标属性”以找到导致此问题的绑定从绑定错误中显示的绑定文本中搜索应用程序中相当独特的内容。在您的情况下,您可以尝试搜索
{x:Type ItemsControl}哪些将成为您的RelativeSource绑定的一部分,并且此类短语的搜索结果不应太多。使用Snoop或WPF Inspector等 3rd 方工具在运行时追踪绑定错误。
我以前只使用过 Snoop,但要使用它,您需要启动您的应用程序并对它运行 Snoop 以在它运行时检查您的应用程序的 VisualTree。然后,您可以通过在搜索栏中键入“MenuItem”之类的内容来搜索 VisualTree 以过滤所有 Visual Tree
MenuItems,然后查看它们的属性以找出哪个具有绑定错误(该HorizontalContentAlignment属性将突出显示为红色,因为绑定错误)。应该注意的是,如果您
MenuItem在 a 内ContextMenu,那么您需要打开它ContextMenu才能绘制 MenuItems 并显示在 Snoop 中。
回答by Raúl Ota?o
Maybe you could use this excellent application named Snoop. It is for free in CodePlex. It helps me to find several Binding issues, and missin data contexts. It let explore the entire WPF Visual tree, and also give you the binding errors.
也许您可以使用这个名为Snoop 的优秀应用程序。它在CodePlex 中是免费的。它帮助我找到了几个绑定问题和缺失的数据上下文。它让您探索整个 WPF 可视化树,并为您提供绑定错误。
Hope Snoop could helps.
希望史努比能帮上忙。
回答by Siamca
I am new to WPF and I have exactly the same error. Although I have fixed it now, I really don't know how... below are steps I have tried:
我是 WPF 的新手,我有完全相同的错误。虽然我现在已经修复了它,但我真的不知道如何......以下是我尝试过的步骤:
First of all, I have:
首先,我有:
- a
<Menu> - 2
<ContextMenu>defined in<ListBox.ItemTemplate>
- 一种
<Menu> - 2
<ContextMenu>定义于<ListBox.ItemTemplate>
I have tried to:
我试图:
- move one
<ContextMenu>into<ListBox.ItemContainerStyle>-> error exists - Set and remove the style
HorizontalContentAlignmentandVerticalContentAlignmentfor<Menu>,<ContextMenu>,<MenuItem>->error exists - Set the
Nameattribute for the<MenuItem>of the<ContextMenu>in<ListBox.ItemTemplate>-> no error! - Remove the
Nameattribute -> still no error... - Restart the VS -> the error seems gone forever...
- 将一个
<ContextMenu>移入<ListBox.ItemContainerStyle>-> 存在错误 - 设置和删除样式
HorizontalContentAlignment和VerticalContentAlignmentfor<Menu>,<ContextMenu>,<MenuItem>->error 存在 - 设置
Name属性为<MenuItem>中的<ContextMenu>中<ListBox.ItemTemplate>- >没有错误! - 删除
Name属性 ->仍然没有错误... - 重新启动 VS ->错误似乎永远消失了......
Eventually, I have
最终,我有
- a
<Menu> - a
<ContextMenu>defined in<ListBox.ItemTemplate> - a
<ContextMenu>defined in<ListBox.ItemContainerStyle>
- 一种
<Menu> - 一个
<ContextMenu>中所定义<ListBox.ItemTemplate> - 一个
<ContextMenu>中所定义<ListBox.ItemContainerStyle>
and NONE of them have set the style HorizontalContentAlignmentand VerticalContentAlignment. And the error has gone...
并且他们都没有设置样式HorizontalContentAlignment和VerticalContentAlignment。错误已经消失了......
Seems there is some refresh issue. So, for those who have the same problem, you could try to restart the VS or set the Nameattribute for the <MenuItem>...
似乎有一些刷新问题。所以,对于那些有同样问题的人,你可以尝试重新启动 VS 或设置...的Name属性<MenuItem>。
回答by mli
System.Windows.Data Error: 4 - it isn't your problem, it's a WPF know problem. It's related comboboxes / menus whose items are changed dynamically. See this. By the way you can ignore this errors, usually application works fine.
System.Windows.Data 错误:4 - 这不是您的问题,而是 WPF 已知问题。它是相关的组合框/菜单,其项目是动态更改的。看到这个。顺便说一句,您可以忽略此错误,通常应用程序可以正常工作。

