2
votes

I have a WPF user control that contains a telerik RadGridView. The control's data context is being set to an instance of MyViewModel class. The MyViewModel class has a myRecords property, of type ObservableCollection. The RadGridView is bound thus:

ItemsSource="{Binding myRecords}"

In the RadGridView I define a number of columns, which contain DataTemplates that bind to properties of MyRecords. This is working fine.

I've added a column that contains a delete button. Or rather, that contains a DataTemplate that contains a button labeled "delete". This is bound to a command defined on the record:

<telerik:GridViewColumn.CellTemplate>
    <DataTemplate>
        <Button 
                Command="{Binding deleteCommand}"
                CommandParameter="{Binding}">
            <Label>Delete</Label>
        </Button>
    </DataTemplate>
</telerik:GridViewColumn.CellTemplate>

And this works fine. The ICommand property I've defined on MyRecord executes.

But here's the thing - that's not where I want this code. I don't want to run a method on MyRecord, I want to run a method on MyViewModel, passing the appropriate MyRecord as an argument. The CommandParameter="{Binding}" element, above, passes the appropriate MyRecord, so that part is fine. But I've not been able to figure out how to bind the button's command to an ICommand on the MyViewModel object, instead of on the MyRecord.

I've been playing around with RelativeSource and AncestorType, and gotten nowhere.

Help would be appreciated.

2

2 Answers

1
votes

One possible approach would be to use a ViewModel for you record which would wrap your model record and also include an ICommand reference. When the initializing each recordViewModel one for each record

recordViewModel.deleteCommand = myViewModel.deleteCommand;

where recordViewModel and myViewModel are instances of the corresponding classes.

This way when the Delete button in the row is clicked the deleteCommand in the parent DataContext will execute.

Update: I found a potential alternate solution that where you bind to a different element so that you are not restricted to the data context of your item and instead use the data context of whatever element you specify.

Command="{Binding DataContext.MyCommand, ElementName=LayoutRoot}"

reference: http://blog.kevindockx.com/post/MVVM-challenge-binding-to-a-command-from-inside-an-ItemsControl-DataTemplate.aspx

0
votes

You could make this using FindAncestor, like this: {Binding DataContext.DeleteCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}.

I think it will be a better solution.