C# WPF数据绑定仅适用于显式ElementName属性

C# WPF数据绑定仅适用于显式ElementName属性,c#,wpf,xaml,data-binding,dependency-properties,C#,Wpf,Xaml,Data Binding,Dependency Properties,我用两个依赖属性创建了第一个自定义控件。一个是decimal,另一个是我自己的CustomType。因此,为了测试它,我创建了一个只有一个窗口的小项目,并尝试使用窗口本身作为数据上下文绑定到它,如下所示: <somethin:mycontrol MyDependencyProperty="{Binding MyCustomType}"/> <Window x:Class="BC.WPF.TestArea.MainWindow" ... x:Name="MyWindow">

我用两个依赖属性创建了第一个自定义控件。一个是
decimal
,另一个是我自己的
CustomType
。因此,为了测试它,我创建了一个只有一个窗口的小项目,并尝试使用窗口本身作为数据上下文绑定到它,如下所示:

<somethin:mycontrol MyDependencyProperty="{Binding MyCustomType}"/>
<Window x:Class="BC.WPF.TestArea.MainWindow" ... x:Name="MyWindow">
...
      <somethin:mycontrol MyDependencyProperty="{Binding ElementName=MyWindow, Path=MyCustomType}"/>

....
</Window>
<ItemsControl ItemsSource="{Binding ElementName=MyWindow, Path=ObservableMyCustomTypes }">
    <ItemsControl.ItemTemplate>
        <DataTemplate DataType="system:Tuple" >
            <StackPanel Orientation="Horizontal" >
                <Label Content="{Binding Item1.Name }"/>
                <somethin:mycontrol  MyDependencyProperty="{Binding Item1}" />
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
IsChecked="{Binding UseFix, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
根据我的经验,ElementName部分不应该是必需的,但它正在工作,所以我很满意,直到我尝试在ItemsControl中使用它。然后事情变得很奇怪。首先,我尝试了这个:

<ItemsControl ItemsSource="{Binding ElementName=MyWindow, Path=ObservableMyCustomTypes }">
    <ItemsControl.ItemTemplate>
        <DataTemplate DataType="somehting:CustomType" >
            <StackPanel Orientation="Horizontal" >
                <Label Content="{Binding Name }"/>
                <somethin:mycontrol  MyDependencyProperty="{Binding}" />
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
令人难以置信的是,标签中对
Item1.Name
的绑定有效,而另一个绑定无效,这让我很困惑,因为现在我真的看不出路径有什么问题,但是
ElementName=MyWindow
的绑定工作正常

发生了什么事


如果你好奇的话

首先,通过设置
DataContext=this来中断控件中的
DataContext
继承PercentageOrFixControl
的构造函数中,因此表达式

PercentageOrFixed="{Binding }"
正在返回控件本身,而不是集合中的
PercentageOrFixed
项。标签的数据上下文是集合的项,这就是它查找
Name
属性的原因

从构造函数中删除数据上下文的setter后,控件中的内部绑定将中断,因为它们查找控件上的属性。加

, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}
到所有绑定的末尾。例如,第一个
单选按钮的
IsChecked
属性应如下所示:

<somethin:mycontrol MyDependencyProperty="{Binding MyCustomType}"/>
<Window x:Class="BC.WPF.TestArea.MainWindow" ... x:Name="MyWindow">
...
      <somethin:mycontrol MyDependencyProperty="{Binding ElementName=MyWindow, Path=MyCustomType}"/>

....
</Window>
<ItemsControl ItemsSource="{Binding ElementName=MyWindow, Path=ObservableMyCustomTypes }">
    <ItemsControl.ItemTemplate>
        <DataTemplate DataType="system:Tuple" >
            <StackPanel Orientation="Horizontal" >
                <Label Content="{Binding Item1.Name }"/>
                <somethin:mycontrol  MyDependencyProperty="{Binding Item1}" />
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
IsChecked="{Binding UseFix, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
编辑
为了进行测试,我删除了
元组的使用,因为它不是必需的,所以集合被定义为
ObservableCollection

谢谢,我刚刚看到应用程序的控制台输出,这给了我一个提示:System.Windows.Data错误:40:BindingExpression路径错误:“object”“PercentageOrFixControl”上未找到Item1属性(名称='').BindingExpression:Path=Item1;DataItem='PercentageOrFixControl'(名称='');目标元素为'PercentageOrFixControl'(名称='');目标属性为'PercentageOrFixed'(类型为'PercentageOrFixed')但是您的回答让它更清楚。非常感谢。与其完全删除DataContext=this,还可以将其更改为按名称设置根面板的DataContext,以获得外部绑定,而不需要将RelativeSource添加到内部的所有内容中。