Button inside DataGrid wpf MVVM
c#, datagrid, events, mvvm, wpf
Solution
The delete command parameter should just be
`CommandParameter="{Binding}"`
this means that the command parameter is the document reference itself thus you can do the following in your command
yourDocumentObservableCollection.Remove(CommandParameter)
This way you wont need to care about if the Document is focused or not.
Problem
I am following MVVM in this project. I have WPF datagrid, ItemsSource `(ItemsSource="{Binding Documents}")` binded to an `ObservableCollection<Document>`, SelectedItem `(SelectedItem="{Binding CurrentDocument, Mode=TwoWay}")` binded to `WorkQueueDocument`, I also have used Interaction Triggers to capture the Double click of the mouse - in order to load the selected Document in a New WIndow. ``` <i:Interaction.Triggers> <i:EventTrigger EventName="MouseDoubleClick"> <i:InvokeCommandAction Command="{Binding ShowViewerCommand}" /> </i:EventTrigger> </i:Interaction.Triggers> ``` I Have defined/binded the columns of my datagrid to corresponding attibutes of WorkQueueDocument class. ``` <DataGrid.Columns> <DataGridTextColumn Width="Auto" MinWidth="100" Header="Name" Binding="{Binding Name}"> <DataGridTextColumn.ElementStyle> <Style TargetType="{x:Type TextBlock}"> <Setter Property="Margin" Value="2,0,0,0" /> <Setter Property="ToolTip" Value="{Binding Name}" /> </Style> </DataGridTextColumn.ElementStyle> </DataGridTextColumn> <!-- Many Other Columns Here... --> </DataGrid.Columns> <DataGrid.ColumnHeaderStyle> <!-- I have various designer style's properties defined here --> </DataGrid.ColumnHeaderStyle> ``` I am supposed to load the document when the user selects the row (document) in the grid - for that CurrentDocument property is defined as follows: ``` public WorkQueueDocument CurrentDocument { get { return this.currentDocument; } set { if (this.currentDocument != value) { this.currentDocument = value; this.OnPropertyChanged("CurrentDocument"); this.IsDocumentSelected = true; // If we are in progress already, don't do anything if (!IsLoading && this.currentDocument != null) { IsLoading = true; LoadDocumentBackgroundWorker();// loading documenting async } if (this.currentDocument == null) { this.IsDocumentSelected = false; } } } } ``` Now, the problem is - I want to add a Delete Button column to this datagrid, such that when user presses Delete button - the document gets deleted directly without loading the document. I added following xaml to `<DataGrid.Columns>` ``` <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Button Name="DeleteBatch" Content="Delete" Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.DeleteCommand}" CommandParameter="Delete"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> ``` This `DeleteCommand` ain't getting fired. I tried to figure out WHY and discovered that I have 1st command is in datagrid for loading document on selection of row ``` ItemsSource="{Binding Documents}" ``` 2nd command is on delete button which is in coluumn of above datagrid ``` <Button Name="Delete" Content="Delete" Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.DeleteCommand}" CommandParameter="Delete"> ``` , I am able to access only one command at a time. When i click the button - the row ('obviously') gets selected and executed associated binding for 'SelectedItem' but does not follow up calling the DeleteCommand ( which ideally should ) . But if I remove this 'SelectedItem' property - the deleteCommand gets triggered ( but then i dont get the selected row). Also (while debugging i noticed) the **DeleteCommand gets executed on when we press(click) second time (coz now the row is already selected)** I googled - and found few probable solutions, like Priority Binding and Tunneling , but unable to implement. Please guide me through this. I got this link , but not sure if this is the only way. P.S : 1. I am using WPF , .Net 4.0 and MVVM - Please do not suggest Third Party solutions. [unless the only option]