How to associate a button on a wpf grid with a method on MVVM when I use a caliber chip

I have a Grid in the wpf window that I want to add so that the user can delete some elements by clicking the delete button. The application uses Calibrun Micro to bind the view to the ViewModel.

My question

1- Is it useful to use a button to remove an item from the grid in WPF?

2 How can I bind a button to a method in a virtual machine and in the metd method get a pointer to the element to be deleted?

Edit1

I added buttons this way in the datagrid:

<DataGridTemplateColumn Width="100"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Button Content="Delete" cal:Message.Attach="DeleteFromList($dataContext)" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> 

and C # code:

  public void DeleteFromList(object tmp) { } 

But the buttons on the datagrid are disabled, and clicking on them does not start the DeleteFromList method (I checked the use of the debugger).

Why are they disabled? How to enable them?

+6
source share
2 answers

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!

+8
source

You can do something like this ...

 <Button cal:Message.Attach="[Event MouseEnter] = [Action Save($this)]"> 

Check the docs as they explain what you need to do, and answer your question:

+1
source

Source: https://habr.com/ru/post/954494/


All Articles