在 UserControl 中设置 DataContext 会影响父级中的绑定

发布于 2024-12-06 18:57:00 字数 1687 浏览 1 评论 0原文

我有一个基本的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

左岸枫 2024-12-13 18:57:00

控件的声明和实例化基本上是在操作同一个对象,声明中设置的所有属性也在每个实例上设置。因此,如果属性是“可见的”,可以这么说:

<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" 
                       DataContext="{Binding RelativeSource={RelativeSource Self}}"
                       PropertyOnChild="{Binding PropertyInParentContext}"/>
</UserControl>

这就是为什么您不设置 UserControlsDataContext,它将覆盖继承的 DataContext >(甚至混淆了存在不同上下文的事实)。如果您想在其声明中绑定到 UserControl 的属性,请为该控件命名并使用 ElementNameRelativeSource-绑定。

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:

<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" 
                       DataContext="{Binding RelativeSource={RelativeSource Self}}"
                       PropertyOnChild="{Binding PropertyInParentContext}"/>
</UserControl>

This is why you do not set the DataContext of UserControls, it will override the inherited DataContext (and even obfuscate the fact that there is a different context). If you want to bind to properties of the UserControl in its declaration then name the control and use ElementName or RelativeSource-bindings instead.

秉烛思 2024-12-13 18:57:00

Self 表示 UserControl,因此当您将 DataContext 设置为 Self 时,您正在设置 DataContextUserControl 对象。

绑定到控件的 DataContext 的正确语法是 {BindingrelativeSource={RelativeSource Self}, Path=DataContext},但是由于 DataContext 是由父级继承的,因此在任何情况下,绑定都是完全没有必要的。

另外,如果您将 DataContext 绑定到 Self.DataContext,那么您实际上会创建一个循环,其中值绑定到自身。

Self means the UserControl, so when you set the DataContext to Self, you are setting the DataContext to the UserControl 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 to Self.DataContext, you would essentially be creating a loop where a value is bound to itself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文