tags:

views:

42

answers:

1

I've got a problem with binding in XAML/WPF. I created Action class which extends FrameworkElement. Each Action has list of ActionItem. The problem is that the Data/DataContext properties of ActionItem are not set, so they are always null.

XAML:

<my:Action DataContext="{Binding}">
    <my:Action.Items>
        <my:ActionItem DataContext="{Binding}" Data="{Binding}" />
    </my:Action.Items>
</my:Action>

C#:

public class Action : FrameworkElement
{
    public static readonly DependencyProperty ItemsProperty =
        DependencyProperty.Register("Items", typeof(IList), typeof(Action), 
                                    new PropertyMetadata(null, null), null);

    public Action()
    {
        this.Items = new ArrayList();
        this.DataContextChanged += (s, e) => MessageBox.Show("Action.DataContext");
    }

    public IList Items
    {
        get { return (IList)this.GetValue(ItemsProperty); }
        set { this.SetValue(ItemsProperty, value); }
    }
}

public class ActionItem : FrameworkElement
{
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(ActionItem),
            new PropertyMetadata(
                null, null, (d, v) =>
                {
                    if (v != null)
                        MessageBox.Show("ActionItem.Data is not null");
                    return v;
                }
            ), null
        );

    public object Data
    {
        get { return this.GetValue(DataProperty); }
        set { this.SetValue(DataProperty, value); }
    }

    public ActionItem()
    {
        this.DataContextChanged += (s, e) => MessageBox.Show("ActionItem.DataContext");
    }
}

Any ideas?

+2  A: 

Items are not children of Action control, so DataContext is not propagates to its. You may do few things to fix it.

The simplest way is override Action.OnPropertyChanged method, and if Property == e.DataContextProperty then assign e.NewValue to each action item. It is simplest but not very good solution, because if your add new action to Items list it will not get current data context.

Second way is inherit Action from ItemsControl, and provide custom control template for it.

STO
I've changed Action base class to ItemsControl and it works. THX.
Lolo
@Lolo accept this answer if it ended up being the right one, click on the checkmark to the left of it.
Donnie