开发者

How to bind to property of property in WPF?

What works

I have a window with a widget and such binding:

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

and in code of the window I set main data context and the data context to this widget:

    public Controller controller { get; set; }

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

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

The property "controller" is in such simple form, because during the lifetime of the window it never changes.

What does not work

I would like to have one data context and use nested binding, such as:

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

And code

    public WorkflowWindow(Controller con)
    {
        controller = con;

        InitializeComponent();
        DataContext = this;
    }

In this case widget is always disabled.

And little variation of it

    public WorkflowWindow(Controller con)
    {
        controller = con;

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

In this case widget is always enabled (this not a typo here).

The question

How to make the second form working? I prefer the second form because then I could bind to various sources, not only from one data context.

SOLVED

Tom开发者_如何学C hit the nail in the head -- the problem was because of the nesting -- the button is part of custom control, and I was setting the data context twice. Once when defining the control, the second time when using it (like here). So that is why WPF got confused -- and I spent two days tracking the problem, oh boy :-(


well you can do it simpler because the DataContext property is among the few that are inherited, which means that when set on an element somewhere in the tree, all child elements get it implicitly if they do not override it.

So your windows's code could look something like:

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

and then your button should look like:

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

so what happens when wpf's binding engine tries to resolve the CanBeEnabled property:

  1. it will look at button's DataContext.
  2. the button's DataContext is not explicitly set, but is inherited from the Window in which the button is placed (WorkflowWindow).
  3. wpf will get the CanBeEnabled property from the DataContext, which (as assigned) is the passed to the Window's contstructor controller.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜