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

时间:2014-04-24 14:56:23

标签: c# wpf xaml data-binding dependency-properties

我创建了第一个具有两个依赖项属性的自定义控件。一个是decimal,另一个是我自己的CustomType。所以为了测试它,我创建了一个只有一个窗口的小项目,并试图通过使用Window本身作为数据上下文来绑定它:

<somethin:mycontrol MyDependencyProperty="{Binding MyCustomType}"/>

其中MyCustomType是MainWindow.cs中的一个属性,但这不起作用。所以我做了一个猜测并给了MainWindow一个名字,然后指定了Element名称,它的工作原理如下:

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

....
</Window>

因此,根据我的经验,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>

这里奇怪的是,CustomType具有Name属性,标签中的Content绑定有效但MyDependencyProperty="{Binding}"不起作用。我还尝试MyDependencyProperty="{Binding .}"但没有成功,所以出于好奇,我尝试将类型Tuple<CustomType>的元素放入集合中,然后绑定到Item1,如下所示:

<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>

令人难以置信的是,标签中的绑定到Item1.Name有效但另一个绑定并没有让我感到困惑,因为现在我真的不知道这可能是什么问题。路径,但ElementName=MyWindow的路径按预期工作。

发生了什么事?

Here is a link to a zip with the complete test project如果你好奇的话。

1 个答案:

答案 0 :(得分:2)

首先,您可以在DataContext的构造函数中设置DataContext = this;,从而在您的控件中中断PercentageOrFixControl继承,因此表达式

PercentageOrFixed="{Binding }"

返回控件本身,而不是集合中的PercentageOrFixed项。标签的数据上下文是集合的项目,以及它找到Name属性的原因。

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

, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}

到所有绑定的结尾。例如,第一个IsChecked的{​​{1}}属性应如下所示:

RadioButton

修改

为了进行测试,我删除了IsChecked="{Binding UseFix, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" 的使用,因为它不需要,因此集合定义为Tuple