使用`ElementName`的WPF绑定失败但在Path属性中指定ElementName有效吗?

时间:2016-05-20 04:41:03

标签: c# wpf data-binding

我的项目中有这个xaml:

<UserControl x:Class="MyControl"
            ... x:Name="Control">

 <Grid x:Name="DetailsGrid" > // <-- I set the data object on this in code
    <Button x:Name="IconBtn" IsEnabled="{Binding IsEditing, ElementName=Control}" 
        Style="{DynamicResource ImageButton}" Click="IconBtn_Click" >
...
<Grid>
</UserControl>

我在IsEditing类中定义了MyControl依赖属性。

namespace MyNamespace
{

    public partial class MyControl : UserControl, INotifyPropertyChanged
    {
       ...
       public bool IsEditing { get; set; }
       ....
    }
}

上述代码无法启用/禁用IconBtn按钮。 但以下绑定IsEnabled="{Binding Control.IsEditing}"的工作原理。

<UserControl x:Class="MyControl"
        ... x:Name="Control">
<Grid x:Name="DetailsGrid" > // <-- I set the data object on this in code
    <Button x:Name="IconBtn" IsEnabled="{Binding Control.IsEditing}" 
        Style="{DynamicResource ImageButton}" Click="IconBtn_Click" >
...
<Grid>
</UserControl>

请告诉我

之间的区别
IsEnabled="{Binding IsEditing, ElementName=Control}"

IsEnabled="{Binding Control.IsEditing}" 

我是WPF和C#的新手。

修改 但这适用于同一个xaml的其他部分:

IsReadOnly="{Binding IsEditing ElementName=Control}"

1 个答案:

答案 0 :(得分:1)

在绑定表达式中使用Path将在DataContext中搜索它,而不是在控件属性中搜索它。如果要直接绑定到控件的属性,则必须使用ElementName语法指定它。当您编写{Binding Control.IsEditing}之类的内容时,WPF会默认搜索您的控件的DataContext以获取名为“Control”的属性,但显然无法找到该属性。

另一种方法是将DataContext设置为控件本身。这可以在构造函数中轻松完成。

修改

阅读您的评论,如果您正在DataContext = this,那么您的DataContext已经设置为控件本身。在这种情况下,您应该只使用{Binding IsEditing},即您无需指定ElementName或限定Control.IsEditing之类的路径。如果您使用Control.限定路径,WPF将尝试在控件中找到名为Control的属性,这显然不存在。

总而言之,您有3个选择:

  1. 指定x:Name并使用{Binding IsEditing, ElementName=XNAME_OF_YOUR_CONTROL}语法。此选项不要求您在构造函数中设置DataContext
  2. 请勿指定x:Name,设置DataContext(DataContext = this;)并使用语法{Binding IsEditing}
  3. 使用RelativeSource={RelativeSource AncestorType=UserControl}Path=IsEditing
  4. 结合使用,指定源对象