Friday, January 7, 2011

WPF DataGrid – Row Double Click

The DataGrid in WPF has no special event handler to handle mouse double clicks on a row. If it had, you could easily determine the row that was clicked and could gain access to the underlying data. This blog entry shows a possible solution by implementing the standard mouse event handler. In short terms it looks for the element under the mouse cursor to determine if it’s a row and in that case gets the selected element of the grid.
Let’s start by defining the DataGrid in the view:

<DataGrid x:Name="dataGrid" MouseDoubleClick="DataGrid_MouseDoubleClick"/>

The definition already contains an event handler for the double click event of the mouse. The binding of the data happens in code and is intentionally left out for brevity. In the example a simple DataSet was used. So let’s have a look at the event handler implementation:

private void DataGrid_MouseDoubleClick(object sender,
                                  System.Windows.Input.MouseButtonEventArgs e)
{
    IInputElement element = e.MouseDevice.DirectlyOver;
    if(element != null && element is FrameworkElement)
    {
        if (((FrameworkElement)element).Parent is DataGridCell)
        {
            var grid = sender as DataGrid;
            if (grid != null && grid.SelectedItems != null
&& grid.SelectedItems.Count == 1)
            {
                var rowView = grid.SelectedItem as DataRowView;
                if (rowView != null)
                {
                    DataRow row = rowView.Row;
                    //do something with the underlying data
                }
            }
        }
    }
}

The MouseDevice class has a very nice property called DirectlyOver which returns the element that is directly under the mouse cursor when the event handler is called. All that needs to be done now is to check if this element is a FrameworkElement and in that case if its parent is a DataGridCell. The double click event is fired whenever you click on any element of the grid (e.g. header, row selector, etc.). But we are only interested in rows and so we check if a cell was clicked and only do further processing if that was the case. The rest is very easy. We get the selected item from the grid and cast it to DataRowView because the underlying data source is a DataSet. If you used another object just cast to that object. The DataRowView has a Row property which represents the underlying data.