This depends on how your button is placed - is there a single 'delete' button or have you added a button per row in the grid (are we talking DataGrid
or just Grid
?)
Assuming you are talking about DataGrid
, you can easily just add an action message command to the button and pass through the item which is being deleted to the message handler on the VM
e.g. in the VM
public class MyViewModel
{
public DataItemCollectionTypeName ItemCollection { get; set; }
public void DeleteItem(DataItemTypeName item)
{
ItemCollection.Remove(item);
}
}
Assuming ItemCollection
is bound to the grid, the button XAML may look like this:
<Button cal:Message.Attach="[Click] = [DeleteItem($datacontext)]" />
You may also need to set Action.TargetWithoutContext
(it should be bound to the VM) if this is a templated row, as otherwise CM will not be able to locate the VM to invoke the action message on
If you have a single button that isn't contained within the grid you can always target the grids SelectedItem
in the action message
<DataGrid x:Name="SomeDataGrid"></DataGrid>
<Button cal:Message.Attach="[Click] = [DeleteItem(SomeDataGrid.SelectedItem)]" />
It may be (and probably is) the default property that CM will look at so you may not need to specify the property name unless you have modified default conventions
<DataGrid x:Name="SomeDataGrid"></DataGrid>
<Button cal:Message.Attach="[Click] = [DeleteItem(SomeDataGrid)]" />
Edit
To clarify: In order for CM to find a VM to call the DeleteItem
method it uses the DataContext
of the current item. In the case of an ItemsControl
derived control, the datacontext for each item points to the item being bound, not the ViewModel.
In order to give CM a hint as to which object it should try to resolve the DeleteItem
method on, you can use the Action.TargetWithoutContext
attached property, which applies a target object for action messages without changing the DataContext
of the bound row/item
You can use element name syntax to point to the correct place:
In this example I've used a grid as the root element and named it LayoutRoot
, then I've pointed the action message target to LayoutRoot.DataContext
(which will be the ViewModel) using ElementName
syntax. You can use any method (AncestorType
or whatever)
<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>
That should then work!