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添加到内部的所有内容中。