是否有一种方法可以确定在哪里声明/创建WPF绑定?

时间:2022-08-24 13:08:39

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。数据错误:4:无法找到与引用'RelativeSource FindAncestor、AncestorType='System.Windows.Controls. controls .进行绑定的源。ItemsControl”,AncestorLevel =“1”。BindingExpression:路径= HorizontalContentAlignment;DataItem =零;目标元素是'MenuItem' (Name= ");目标属性为' horizontalcontentalign '(类型为' horizontalalign ')

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
  • 为System.Windows添加了调试跟踪。数据命名空间与水平集o所有;这并没有产生更多有用的信息
  • tried doing a text-search in the project for the word Binding in 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..
  • 尝试在项目中对单词绑定进行文本搜索,希望找到所有路径设置为horizontalcontentalign的绑定表达式;我只找到了一个,并删除了它,但我仍然得到的信息似乎表明那不是错误的。

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 HorizontalContentAlignment on all MenuItems. The reason for the error is somehow related to order of operations as this MenuItem is generated in code. I'll post a new question on that separately.

事实证明,绑定是用样式声明的。这个样式不在我的应用中。它可能是MenuItem的默认样式。为了解决这个问题,我已经手动设置了所有MenuItems的horizontalcontentalign。这个错误的原因在某种程度上与操作顺序有关,因为这个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 MenuItems here.

我在这里发布了另一个关于应用于MenuItems的样式/绑定的问题。

4 个解决方案

#1


85  

When debugging WPF binding errors, I find it easiest to break up the error by the semicolons, and start from the end

在调试WPF绑定错误时,我发现用分号分隔错误并从末尾开始是最容易的

  1. System.Windows.Data Error: 4 :
  2. System.Windows。数据错误:4:
  3. Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. BindingExpression:Path=HorizontalContentAlignment;
  4. 无法找到与引用'RelativeSource FindAncestor、AncestorType='System.Windows.Controls. controls .进行绑定的源代码。ItemsControl”,AncestorLevel =“1”。BindingExpression:路径= HorizontalContentAlignment;
  5. DataItem=null;
  6. DataItem =零;
  7. target element is 'MenuItem' (Name='');
  8. 目标元素为'MenuItem' (Name= ");
  9. target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment')
  10. 目标属性为' horizontalcontentalign '(类型为' horizontalalign ')

So starting from the end:

所以从结尾开始

  • #5 tells you what property contains the binding that is failing. In your case, it's HorizontalContentAlignment

    #5告诉您什么属性包含正在失败的绑定。在您的例子中,它是horizontalcontentalign

  • #4 is the element containing the failing property, which is a MenuItem without a Name property to identify it by

    #4是包含失败属性的元素,它是一个MenuItem,没有名称属性来标识它

    So somewhere you have a <MenuItem HorizontalContentAlignment="{Binding ...}" /> that is causing the binding error.

    因此,在某个地方有一个,导致绑定错误。

  • #3 is the DataItem, or DataContext, that is behind the target element. It appears to be null for you, but that's not a problem since it looks like your binding isn't referencing the DataContext.

    #3是目标元素后面的DataItem或DataContext。它对您来说似乎是空的,但这不是问题,因为看起来您的绑定没有引用DataContext。

    But this does suggest that the MenuItem is not part of your regular VisualTree, since typically the DataContext is inherited from the parent object.

    但这确实表明MenuItem不是常规VisualTree的一部分,因为通常DataContext是从父对象继承的。

  • #2 contains the actual binding error and information about the binding. It can actually be further broken up into multiple parts.

    #2包含实际的绑定错误和有关绑定的信息。它实际上可以被进一步分解成多个部分。

    • Cannot find source for binding

      无法找到绑定源。

    • with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''.

      使用reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls。ItemsControl”,AncestorLevel =“1”。

    • BindingExpression:Path=HorizontalContentAlignment;

      BindingExpression:路径= 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} (FindAncestor and AncestorLevel=1 are defaults for a RelativeSource, so I'm ignoring those)

    “找不到源”意味着绑定无法找到要绑定的源对象,在您的例子中,源对象应该是{RelativeSource AncestorType={x: ItemsControl} (FindAncestor和AncestorLevel=1是相对论源的默认值,所以我忽略了这些)

    And the last part of #2 shows the Path you are trying to bind to: HorizontalContentAlignment

    #2的最后一部分显示了您试图绑定到的路径:horizontalcontentalign

So to put it all together, somewhere in your code there is a <MenuItem> which is trying to bind its HorizontalContentAlignment to an ItemsControl.HorizontalContentAlignment, but the binding can't find the ItemsControl.

因此,要将它们放在一起,代码中的某个地方有一个,它试图将它的horizontalcontentalign绑定到items控件。horizontalcontentalign,但是绑定不能找到ItemsControl。

You're using a RelativeSource FindAncestor binding 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 ItemsControl higher up in the VisualTree hierarchy from the MenuItem.

您正在使用一个RelativeSource FindAncestor绑定来查找ItemsControl, ItemsControl在可视化树中搜索以找到最近的ItemsControl,但它没有找到,因此必须在VisualTree层次结构中没有来自MenuItem的ItemsControl。

I often see this problem with ContextMenus because they are not part of the same VisualTree as the rest of your XAML code. (To reference the object in the main VisualTree that a ContextMenu is attached to, you can use the PlacementTarget property, like this example.

我经常在contextmenu中看到这个问题,因为它们与XAML代码的其他部分不属于相同的VisualTree。(要引用ContextMenu附加到的主VisualTree中的对象,可以使用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 binding

    从绑定错误(在您的示例中是MenuItem)中搜索应用程序的“目标元素”,并查看它们是否正在使用绑定设置“目标属性”(horizontalcontentalign)

  • Search the application for the "target property" from the binding error (HorizontalContentAlignment) to find the binding causing this problem

    从绑定错误(horizontalcontentalign)中搜索应用程序的“目标属性”,查找导致此问题的绑定

  • Search 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 your RelativeSource binding, and there shouldn't be too many search results for such a phrase.

    从绑定错误中显示的绑定文本中搜索应用程序,寻找一些相当独特的内容。在您的例子中,您可以尝试在{x:Type ItemsControl}上搜索,这将是您的相对论源绑定的一部分,对于这样一个短语,不应该有太多的搜索结果。

  • Use a 3rd party tool like Snoop or WPF Inspector to track down the binding error at run time.

    使用像Snoop或WPF检查器这样的第三方工具来跟踪运行时的绑定错误。

    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 (the HorizontalContentAlignment property will be highlighted in red because of the binding error).

    我以前只使用过Snoop,但是要使用它,您需要启动应用程序并对其运行Snoop,以便在应用程序运行时检查其VisualTree。然后,您可以通过在搜索栏中输入类似“MenuItem”的东西来搜索VisualTree,以筛选所有MenuItems的可视化树,然后查看它们的属性,找出哪个有绑定错误(horizontalcontentalign属性将由于绑定错误而用红色突出显示)。

    It should be noted that if if your MenuItem is inside a ContextMenu, then you need to open that ContextMenu for the MenuItems to be drawn and show up in Snoop.

    需要注意的是,如果MenuItem位于ContextMenu中,则需要打开该ContextMenu以便在Snoop中绘制和显示菜单项。

#2


4  

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上是免费的。它帮助我找到几个绑定问题,以及missin数据上下文。它让您可以探索整个WPF的可视树,并给出绑定错误。

Hope Snoop could helps.

希望Snoop能帮助。

#3


1  

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:

首先,我有:

  1. a <Menu>
  2. <菜单>
  3. 2 <ContextMenu> defined in <ListBox.ItemTemplate>
  4. 2 定义在

I have tried to:

我有尝试:

  1. move one <ContextMenu> into <ListBox.ItemContainerStyle> -> error exists
  2. 将一个 移动到 - >错误存在 。itemcontainerstyle>
  3. Set and remove the style HorizontalContentAlignment and VerticalContentAlignment for <Menu>, <ContextMenu>, <MenuItem> ->error exists
  4. 设置并删除 ->存在错误
  5. Set the Name attribute for the <MenuItem> of the <ContextMenu> in <ListBox.ItemTemplate> -> no error!
  6. 设置 的Name属性。ItemTemplate > - >没有错误!
  7. Remove the Name attribute -> still no error...
  8. 删除Name属性->仍然没有错误…
  9. Restart the VS -> the error seems gone forever...
  10. 重新启动VS ->,错误似乎永远消失了……

Eventually, I have

最后,我有

  1. a <Menu>
  2. <菜单>
  3. a <ContextMenu> defined in <ListBox.ItemTemplate>
  4. 中定义的
  5. a <ContextMenu> defined in <ListBox.ItemContainerStyle>
  6. 中定义的

and NONE of them have set the style HorizontalContentAlignment and VerticalContentAlignment. And the error has gone...

他们都没有设置样式horizontalcontentalign和verticalcontentalign。错误消失了……

Seems there is some refresh issue. So, for those who have the same problem, you could try to restart the VS or set the Name attribute for the <MenuItem>...

似乎有一些更新问题。因此,对于有相同问题的人,您可以尝试重新启动VS或设置的Name属性……

#4


-1  

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。数据错误:4 -这不是你的问题,这是一个WPF知道的问题。它是相关的组合框/菜单,它们的项是动态变化的。看到这个。顺便说一下,您可以忽略这些错误,通常应用程序可以正常工作。

#1


85  

When debugging WPF binding errors, I find it easiest to break up the error by the semicolons, and start from the end

在调试WPF绑定错误时,我发现用分号分隔错误并从末尾开始是最容易的

  1. System.Windows.Data Error: 4 :
  2. System.Windows。数据错误:4:
  3. Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. BindingExpression:Path=HorizontalContentAlignment;
  4. 无法找到与引用'RelativeSource FindAncestor、AncestorType='System.Windows.Controls. controls .进行绑定的源代码。ItemsControl”,AncestorLevel =“1”。BindingExpression:路径= HorizontalContentAlignment;
  5. DataItem=null;
  6. DataItem =零;
  7. target element is 'MenuItem' (Name='');
  8. 目标元素为'MenuItem' (Name= ");
  9. target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment')
  10. 目标属性为' horizontalcontentalign '(类型为' horizontalalign ')

So starting from the end:

所以从结尾开始

  • #5 tells you what property contains the binding that is failing. In your case, it's HorizontalContentAlignment

    #5告诉您什么属性包含正在失败的绑定。在您的例子中,它是horizontalcontentalign

  • #4 is the element containing the failing property, which is a MenuItem without a Name property to identify it by

    #4是包含失败属性的元素,它是一个MenuItem,没有名称属性来标识它

    So somewhere you have a <MenuItem HorizontalContentAlignment="{Binding ...}" /> that is causing the binding error.

    因此,在某个地方有一个,导致绑定错误。

  • #3 is the DataItem, or DataContext, that is behind the target element. It appears to be null for you, but that's not a problem since it looks like your binding isn't referencing the DataContext.

    #3是目标元素后面的DataItem或DataContext。它对您来说似乎是空的,但这不是问题,因为看起来您的绑定没有引用DataContext。

    But this does suggest that the MenuItem is not part of your regular VisualTree, since typically the DataContext is inherited from the parent object.

    但这确实表明MenuItem不是常规VisualTree的一部分,因为通常DataContext是从父对象继承的。

  • #2 contains the actual binding error and information about the binding. It can actually be further broken up into multiple parts.

    #2包含实际的绑定错误和有关绑定的信息。它实际上可以被进一步分解成多个部分。

    • Cannot find source for binding

      无法找到绑定源。

    • with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''.

      使用reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls。ItemsControl”,AncestorLevel =“1”。

    • BindingExpression:Path=HorizontalContentAlignment;

      BindingExpression:路径= 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} (FindAncestor and AncestorLevel=1 are defaults for a RelativeSource, so I'm ignoring those)

    “找不到源”意味着绑定无法找到要绑定的源对象,在您的例子中,源对象应该是{RelativeSource AncestorType={x: ItemsControl} (FindAncestor和AncestorLevel=1是相对论源的默认值,所以我忽略了这些)

    And the last part of #2 shows the Path you are trying to bind to: HorizontalContentAlignment

    #2的最后一部分显示了您试图绑定到的路径:horizontalcontentalign

So to put it all together, somewhere in your code there is a <MenuItem> which is trying to bind its HorizontalContentAlignment to an ItemsControl.HorizontalContentAlignment, but the binding can't find the ItemsControl.

因此,要将它们放在一起,代码中的某个地方有一个,它试图将它的horizontalcontentalign绑定到items控件。horizontalcontentalign,但是绑定不能找到ItemsControl。

You're using a RelativeSource FindAncestor binding 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 ItemsControl higher up in the VisualTree hierarchy from the MenuItem.

您正在使用一个RelativeSource FindAncestor绑定来查找ItemsControl, ItemsControl在可视化树中搜索以找到最近的ItemsControl,但它没有找到,因此必须在VisualTree层次结构中没有来自MenuItem的ItemsControl。

I often see this problem with ContextMenus because they are not part of the same VisualTree as the rest of your XAML code. (To reference the object in the main VisualTree that a ContextMenu is attached to, you can use the PlacementTarget property, like this example.

我经常在contextmenu中看到这个问题,因为它们与XAML代码的其他部分不属于相同的VisualTree。(要引用ContextMenu附加到的主VisualTree中的对象,可以使用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 binding

    从绑定错误(在您的示例中是MenuItem)中搜索应用程序的“目标元素”,并查看它们是否正在使用绑定设置“目标属性”(horizontalcontentalign)

  • Search the application for the "target property" from the binding error (HorizontalContentAlignment) to find the binding causing this problem

    从绑定错误(horizontalcontentalign)中搜索应用程序的“目标属性”,查找导致此问题的绑定

  • Search 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 your RelativeSource binding, and there shouldn't be too many search results for such a phrase.

    从绑定错误中显示的绑定文本中搜索应用程序,寻找一些相当独特的内容。在您的例子中,您可以尝试在{x:Type ItemsControl}上搜索,这将是您的相对论源绑定的一部分,对于这样一个短语,不应该有太多的搜索结果。

  • Use a 3rd party tool like Snoop or WPF Inspector to track down the binding error at run time.

    使用像Snoop或WPF检查器这样的第三方工具来跟踪运行时的绑定错误。

    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 (the HorizontalContentAlignment property will be highlighted in red because of the binding error).

    我以前只使用过Snoop,但是要使用它,您需要启动应用程序并对其运行Snoop,以便在应用程序运行时检查其VisualTree。然后,您可以通过在搜索栏中输入类似“MenuItem”的东西来搜索VisualTree,以筛选所有MenuItems的可视化树,然后查看它们的属性,找出哪个有绑定错误(horizontalcontentalign属性将由于绑定错误而用红色突出显示)。

    It should be noted that if if your MenuItem is inside a ContextMenu, then you need to open that ContextMenu for the MenuItems to be drawn and show up in Snoop.

    需要注意的是,如果MenuItem位于ContextMenu中,则需要打开该ContextMenu以便在Snoop中绘制和显示菜单项。

#2


4  

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上是免费的。它帮助我找到几个绑定问题,以及missin数据上下文。它让您可以探索整个WPF的可视树,并给出绑定错误。

Hope Snoop could helps.

希望Snoop能帮助。

#3


1  

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:

首先,我有:

  1. a <Menu>
  2. <菜单>
  3. 2 <ContextMenu> defined in <ListBox.ItemTemplate>
  4. 2 定义在

I have tried to:

我有尝试:

  1. move one <ContextMenu> into <ListBox.ItemContainerStyle> -> error exists
  2. 将一个 移动到 - >错误存在 。itemcontainerstyle>
  3. Set and remove the style HorizontalContentAlignment and VerticalContentAlignment for <Menu>, <ContextMenu>, <MenuItem> ->error exists
  4. 设置并删除 ->存在错误
  5. Set the Name attribute for the <MenuItem> of the <ContextMenu> in <ListBox.ItemTemplate> -> no error!
  6. 设置 的Name属性。ItemTemplate > - >没有错误!
  7. Remove the Name attribute -> still no error...
  8. 删除Name属性->仍然没有错误…
  9. Restart the VS -> the error seems gone forever...
  10. 重新启动VS ->,错误似乎永远消失了……

Eventually, I have

最后,我有

  1. a <Menu>
  2. <菜单>
  3. a <ContextMenu> defined in <ListBox.ItemTemplate>
  4. 中定义的
  5. a <ContextMenu> defined in <ListBox.ItemContainerStyle>
  6. 中定义的

and NONE of them have set the style HorizontalContentAlignment and VerticalContentAlignment. And the error has gone...

他们都没有设置样式horizontalcontentalign和verticalcontentalign。错误消失了……

Seems there is some refresh issue. So, for those who have the same problem, you could try to restart the VS or set the Name attribute for the <MenuItem>...

似乎有一些更新问题。因此,对于有相同问题的人,您可以尝试重新启动VS或设置的Name属性……

#4


-1  

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。数据错误:4 -这不是你的问题,这是一个WPF知道的问题。它是相关的组合框/菜单,它们的项是动态变化的。看到这个。顺便说一下,您可以忽略这些错误,通常应用程序可以正常工作。