views:

1581

answers:

1

I am using the M-V-VM pattern in a WPF app. I am binding a ViewModel to a COntentControl and using a data template defined int eh window resources to render the view (a UserControl) for that ViewModel.

In the ViewModel, I have a collection of items. I'm binding that collection to the data grid provided in the WPF toolkit. Also in the view model, I have a RemoveITem command defined which takes an argument for the item ID to remove.

How would I bind to that command in the data grid? The grid's data context is that collection, so something like:

<Button Command="{Binding Path=RemoveCommand}" CommandParameter="{Binding Path=id}">X</Button>

doesn't work - it can't find the command. I think I need to do RelativeSource binding, but what would that look like? Would the Ancestor type be USerControl, or the ContentControl? Where is my ViewModel residing as the DataContext?

Or am I way off here?

+5  A: 

Yeah, you just need to get one level up. I'd try a binding with ElementName first and resort to RelativeSource only if necessary. For example, I'd prefer this:

<DataGrid x:Name="_grid">
    ...
        <Button Command="{Binding DataContext.RemoveItem, ElementName=_grid}"/>
    ...
</DataGrid>

That said, the XAML compiler can get its knickers in a knot when it comes to element names and scoping in controls, so you may need to resort to a RelativeSource:

<DataGrid x:Name="_grid">
    ...
        <Button Command="{Binding DataContext.RemoveItem, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"/>
    ...
</DataGrid>

You only need to search up until the data context will be your view model. You could search for a UserControl if you wanted to - not sure it really matters. Both are pretty fragile bindings, which is why I prefer the ElementName approach.

HTH, Kent

Kent Boogaart
Awesome. Thanks, Kent!
Adam Barney
Welcome. Another way to do this is to expose a collection of child view models rather than a collection of data items. Then, those child view models can have a property that exposes the command, saving you from introducing fragile bindings like these.
Kent Boogaart
Thank you, that solved my problem.
Jonathan Allen