It depends on how your button is installed - is there a single βdeleteβ button or is there a button added in a row in the grid (are we talking DataGrid or just Grid ?)
Assuming you're talking about a DataGrid , you can simply add an action command to the button and go through an element that is deleted in the message handler on the virtual machine
eg. in VM
public class MyViewModel { public DataItemCollectionTypeName ItemCollection { get; set; } public void DeleteItem(DataItemTypeName item) { ItemCollection.Remove(item); } }
Assuming ItemCollection is grid-bound, the XAML button might look like this:
<Button cal:Message.Attach="[Click] = [DeleteItem($datacontext)]" />
You may also need to set Action.TargetWithoutContext (it must be bound to VM) if it is a template string, since otherwise CM will not be able to find a virtual machine to call the action message on
If you have one button that is not in the grid, you can always target the SelectedItem grids in the action message
<DataGrid x:Name="SomeDataGrid"></DataGrid> <Button cal:Message.Attach="[Click] = [DeleteItem(SomeDataGrid.SelectedItem)]" />
This may be (and probably) the default property that CM will look at, so you may not need to provide a property name unless you change the default convention
<DataGrid x:Name="SomeDataGrid"></DataGrid> <Button cal:Message.Attach="[Click] = [DeleteItem(SomeDataGrid)]" />
Edit
To clarify: In order for CM to find a virtual machine to call the DeleteItem method, it uses the DataContext current element. In the case of a derived ItemsControl , the datacontext for each item points to the associated item, not to the ViewModel.
To give CM a hint about which object should try to resolve the DeleteItem method, you can use the Action.TargetWithoutContext property, which applies the target object to action messages without changing the DataContext associated row / element
The element name syntax can be used to indicate the correct location:
In this example, I used the grid as the root element and named it LayoutRoot , after which I pointed the target of the action to LayoutRoot.DataContext (which will be ViewModel) using the ElementName syntax. You can use any method ( AncestorType or something else)
<Grid x:Name="LayoutRoot"> <DataGridTemplateColumn Width="100"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Button Content="Delete" cal:Message.Attach="DeleteFromList($dataContext)" cal:Action.TargetWithoutContext="{Binding DataContext, ElementName=LayoutRoot}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </Grid>
Then it will work!