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

Gaz*_*yer 13 data-binding wpf datacontext xaml user-controls

我有一个基本的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>
Run Code Online (Sandbox Code Playgroud)

这在父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>
Run Code Online (Sandbox Code Playgroud)

由于某种原因,这给出了一个绑定错误,似乎表明DataContext父控件的设置受其自身的子控件设置的影响DataContext.

System.Windows.Data错误:40:BindingExpression路径错误:'object'''ChildControl'(Name ='ChildName')'上找不到'PropertyInParentContext'属性.BindingExpression:路径= PropertyInParentContext; DataItem ='ChildControl'(Name ='ChildName'); target元素是'ChildControl'(Name ='ChildName'); target属性是'PropertyOnChild'(输入'whatever')

为什么"PropertyInParentContext"在子控件中而不是在父控件中查找DataContext

如果我删除了

DataContext="{Binding RelativeSource={RelativeSource Self}}
Run Code Online (Sandbox Code Playgroud)

从孩子控制,然后事情运作我期望.

我错过了一些明显的东西吗?

H.B*_*.B. 11

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

<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>
Run Code Online (Sandbox Code Playgroud)

这就是为什么你不设置DataContextUserControls,它会覆盖继承DataContext(甚至混淆事实,那就是不同的上下文中).如果要绑定到UserControl其声明中的属性,请为控件命名并使用ElementNameRelativeSource-bindings.


Rac*_*hel 5

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

绑定到Control的正确语法DataContext{Binding RelativeSource={RelativeSource Self}, Path=DataContext},但由于DataContext是由Parent继承的,因此在任何情况下这种绑定都是完全不必要的.

此外,如果你绑定你DataContextSelf.DataContext,你实际上将创建一个循环,其中值绑定到自身.