如何在WPF中绑定属性的属性?

时间:2010-12-19 16:34:06

标签: c# wpf

什么有效

我有一个带有小部件和这种绑定的窗口:

<Button Name="button" IsEnabled="{Binding Path=CanBeEnabled}"/>

在窗口的代码中,我将主数据上下文和数据上下文设置为此小部件:

    public Controller controller { get; set; }

    public WorkflowWindow(Controller con) // constructor
    {
        controller = con;

        InitializeComponent();
        DataContext = this;
        button.DataContext = controller;
    }

属性“controller”的形式很简单,因为在窗口的生命周期中它永远不会改变。

什么不起作用

我想拥有一个数据上下文并使用嵌套绑定,例如:

<Button Name="button" IsEnabled="{Binding Path=controller.CanBeEnabled}"/>

和代码

    public WorkflowWindow(Controller con)
    {
        controller = con;

        InitializeComponent();
        DataContext = this;
    }

在这种情况下,小部件始终处于禁用状态。

它的变化很小

    public WorkflowWindow(Controller con)
    {
        controller = con;

        InitializeComponent();
        DataContext = this;
        button.DataContext = this; // directly setting the data context
    }

在这种情况下,小部件始终启用(这不是拼写错误)。

问题

如何使第二种形式有效?我更喜欢第二种形式,因为我可以绑定到各种来源,而不仅仅是来自一个数据上下文。

解决

汤姆击中头部 - 问题是因为嵌套 - 按钮是自定义控件的一部分,我正在设置数据上下文两次。一旦定义控件,第二次使用它时(如此处)。所以这就是为什么WPF感到困惑 - 我花了两天时间跟踪问题,哦,男孩: - (

1 个答案:

答案 0 :(得分:2)

你可以做得更简单,因为DataContext属性属于少数继承,这意味着当在树中的某个元素上设置时,所有子元素都会得到它隐含地,如果他们不覆盖它。

所以你的windows代码看起来像:

public WorkflowWindow(Controller con)
{
   InitializeComponent();
   DataContext = con;
}

然后您的按钮应如下所示:

<Button IsEnabled="{Binding Path=CanBeEnabled}"/>

所以当wpf的绑定引擎试图解析CanBeEnabled属性时会发生什么:

  1. 它会看按钮的DataContext
  2. 按钮的DataContext未明确设置,但是从放置按钮的窗口继承(WorkflowWindow)。
  3. wpf将从CanBeEnabled获取DataContext属性,其中(已分配)将传递给Window的contstructor控制器。