Getting WPF Data Grid Context Menu Click Row

O.O. picture O.O. · May 29, 2013 · Viewed 38.7k times · Source

I have a WPF DataGrid

<DataGrid AutoGenerateColumns="False"  Name="dataGrid1"  IsReadOnly="True" >
<DataGrid.Columns>
    <DataGridTextColumn Header="Site" Binding="{Binding Site}" Width="150" />
    <DataGridTextColumn Header="Subject" Binding="{Binding Subject}" Width="310" />
</DataGrid.Columns>
<DataGrid.ContextMenu>
    <ContextMenu>
        <MenuItem Header="Delete" Click="Context_Delete">
            <MenuItem.Icon>
                <Image Width="12" Height="12" Source="Images/Delete.png" />
            </MenuItem.Icon>
        </MenuItem>
    </ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>

I have the click event handler as:

private void Context_Delete(object sender, System.EventArgs e)  { }

How do I get the row on which the Context Menu was before the click? The sender object is System.Windows.Controls.MenuItem, not the DataGridRow. How do I get the DataGridRow where the Context Menu was clicked. (I set the DataGrid.ItemSource in the code behind file.)

Answer

dsfgsho picture dsfgsho · May 29, 2013

So based on your example code, I presume you bind your DataGrid to an ObservableCollection of objects of which you bind the properties Site and Subject to the DataGridColumns.

Essentially, all you need to do is figure out what the item bound to the clicked DataGridRow is and remove that from your ObservableCollection. Here is some example code to get you started:

private void Context_Delete(object sender, RoutedEventArgs e)
{
    //Get the clicked MenuItem
    var menuItem = (MenuItem)sender;

    //Get the ContextMenu to which the menuItem belongs
    var contextMenu = (ContextMenu)menuItem.Parent;

    //Find the placementTarget
    var item = (DataGrid)contextMenu.PlacementTarget;

    //Get the underlying item, that you cast to your object that is bound
    //to the DataGrid (and has subject and state as property)
    var toDeleteFromBindedList = (YourObject)item.SelectedCells[0].Item;

    //Remove the toDeleteFromBindedList object from your ObservableCollection
    yourObservableCollection.Remove(toDeleteFromBindedList);
}