在 UserControl 中设置 DataContext 会影响父级中的绑定
我有一个基本的 UserControl
,它将其 DataContext
设置为自身以便于绑定:
<UserControl x:Class="MyControlLib.ChildControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
</UserControl>
这在父 XAML 文件中使用,如下所示:
<UserControl x:Class="MyControlLib.ParentControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ctrl="clr-namespace:MyControlLib">
<ctrl:ChildControl x:Name="ChildName"
PropertyOnChild="{Binding PropertyInParentContext}"/>
</UserControl>
出于某种原因,这会产生绑定错误这似乎表明父控件的 DataContext 受到子控件设置其自己的 DataContext 的影响。
System.Windows.Data 错误:40:BindingExpression 路径错误:在“对象”“ChildControl”(Name=“ChildName”)”上找不到“PropertyInParentContext”属性。 BindingExpression:Path=PropertyInParentContext; DataItem='ChildControl'(Name='ChildName');目标元素是 'ChildControl' (Name='ChildName');目标属性是“PropertyOnChild”(类型“whatever”)
为什么要在子控件而不是父控件的 DataContext 中查找“PropertyInParentContext”?
如果我从子控件中删除
DataContext="{Binding RelativeSource={RelativeSource Self}}
,那么事情就会按照我的预期进行。
我在这里遗漏了一些明显的东西吗?
I have a basic UserControl
that sets its DataContext
to itself for ease of binding:
<UserControl x:Class="MyControlLib.ChildControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
</UserControl>
This is used in a parent XAML file like this:
<UserControl x:Class="MyControlLib.ParentControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ctrl="clr-namespace:MyControlLib">
<ctrl:ChildControl x:Name="ChildName"
PropertyOnChild="{Binding PropertyInParentContext}"/>
</UserControl>
For some reason, this gives a binding error that seems to indicate that the DataContext
of the parent control is getting affected by the child control setting its own DataContext
.
System.Windows.Data Error: 40 : BindingExpression path error: 'PropertyInParentContext' property not found on 'object' ''ChildControl' (Name='ChildName')'. BindingExpression:Path=PropertyInParentContext; DataItem='ChildControl' (Name='ChildName'); target element is 'ChildControl' (Name='ChildName'); target property is 'PropertyOnChild' (type 'whatever')
Why is "PropertyInParentContext" being looking for in the child control rather than in the parent's DataContext
?
If I remove the
DataContext="{Binding RelativeSource={RelativeSource Self}}
from the child control, then things operate how I would expect.
Am I missing something obvious here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
控件的声明和实例化基本上是在操作同一个对象,声明中设置的所有属性也在每个实例上设置。因此,如果属性是“可见的”,可以这么说:
这就是为什么您不设置
UserControls
的DataContext
,它将覆盖继承的DataContext
>(甚至混淆了存在不同上下文的事实)。如果您想在其声明中绑定到UserControl
的属性,请为该控件命名并使用ElementName
或RelativeSource
-绑定。The declaration of your control and the instantiation are basically manipulating the same object, all the properties that are set in the declaration are also set on every instance. So if the properties were "visible" so to speak:
This is why you do not set the
DataContext
ofUserControls
, it will override the inheritedDataContext
(and even obfuscate the fact that there is a different context). If you want to bind to properties of theUserControl
in its declaration then name the control and useElementName
orRelativeSource
-bindings instead.Self
表示UserControl
,因此当您将DataContext
设置为Self
时,您正在设置DataContext
到UserControl
对象。绑定到控件的
DataContext
的正确语法是{BindingrelativeSource={RelativeSource Self}, Path=DataContext}
,但是由于 DataContext 是由父级继承的,因此在任何情况下,绑定都是完全没有必要的。另外,如果您将
DataContext
绑定到Self.DataContext
,那么您实际上会创建一个循环,其中值绑定到自身。Self
means theUserControl
, so when you set theDataContext
toSelf
, you are setting theDataContext
to theUserControl
object.The correct syntax for binding to a Control's
DataContext
would be{Binding RelativeSource={RelativeSource Self}, Path=DataContext}
, however since the DataContext is inherited by the Parent, this binding is totally unncessary in any situation.Also, if you bind your
DataContext
toSelf.DataContext
, you would essentially be creating a loop where a value is bound to itself.