Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding to a command in a datagrid

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 in the 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?

like image 212
Adam Barney Avatar asked Feb 24 '09 13:02

Adam Barney


People also ask

What is command binding in WPF?

The command is the action to be executed. The command source is the object which invokes the command. The command target is the object that the command is being executed on. The command binding is the object which maps the command logic to the command.

What is the difference between grid and DataGrid in WPF?

A Grid is a control for laying out other controls on the form (or page). A DataGrid is a control for displaying tabular data as read from a database for example.

What is WPF DataGrid?

The WPF Data Grid (GridControl) is a data-aware control designed to display and edit data in different layouts: tabular, treelike, and card. The GridControl allows users to manage large amounts of data (sort, group, filter, and so on).


1 Answers

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.

like image 166
Kent Boogaart Avatar answered Oct 02 '22 20:10

Kent Boogaart