Serbin
Serbin

Reputation: 823

Bind SelectedItem to correct DataContext in WPF

I have a UserControl barView and corresponding ViewModel barViewModel. This ViewModel have property SelectedSomething, which is binded to different ListBoxes in my view.

If I have construction like this, then everything woks fine:

<UserControl DataContext="barViewModel">
    <ListBox ItemsSource="{Binding ObservableCollectionWithItems}"
             SelectedItem="{Binding SelectedSomething, Mode=TwoWay}">
        ....
    </ListBox>
</UserControl>

In this case my ViewModel have ObservableCollection with items.

Now I want to split my items to groups. I create a separete class for that:

class ItemsGroup
{
     private string _Name;
     public string Name {...}

     private List<Item> _ItemsList;
     public List<Item> ItemsList {...}
}

My barViewModel now contains a observalbe collection of ItemsGroup objects. New view for this looks like this:

<UserControl DataContext="barViewModel">
<ItemsControl ItemsSource="{Binding ObservalbeCollectionWithItemsGroup}">
    <ItemsControl.ItemTemplate>
        <DataTemplate DataType="{x:Type test:ItemsGroup}">
            <Expander IsExpanded="False">
                <Expander.Header>
                    <TextBlock Content="{Binding Name}"/>
                </Expander.Header>
                <ListBox ItemsSource="{Binding ItemsList}" Margin="10"
                         SelectedItem="{Binding SelectedSomething, Mode=TwoWay}">
                    ...
                </ListBox>
            </Expander>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

The problem is that SelectedItem of ListBox is binded to the parent and show me this error:

System.Windows.Data Error: 40 : BindingExpression path error: 'SelectedSomething' property not found on 'object' ''ItemsGroup' (HashCode=10335672)'. BindingExpression:Path=SelectedSomething; DataItem='ItemsGroup' (HashCode=10335672); target element is 'ListBox' (Name=''); target property is 'SelectedItem' (type 'Object')

I tried to change SelectedItem to this:

Text="{Binding SelectedSomething,
               RelativeSource={RelativeSource Mode=FindAncestor,
                                              AncestorType={x:Type UserControl}}}"

This will remove error, but my SelectedSomething is still not binded to the ListBox. How can I fix this?

Upvotes: 3

Views: 2038

Answers (1)

Clemens
Clemens

Reputation: 128147

When SelectedSomething is a property in your main view model, and the UserControl's DataContext is set to an instance of that view model, the binding should look like this:

SelectedItem="{Binding DataContext.SelectedSomething,
               RelativeSource={RelativeSource AncestorType=UserControl}}"

Note also that it's not necessary to set Mode=TwoWay on the SelectedItem binding, because the property binds two-way by default.

Upvotes: 3

Related Questions