Articles in categories

Articles

Enable single click edit in WPF DataGrid

Normally when you click on a row in the WPF DataGrid, the row and cell is selected. When you want to edit the cell you need to click it again.

I needed it to be editable from the first click. After some searching on the Net I found this solution that works for me. I used this in a UserControl, but it should work just the same in a Window.

UserControl codebehind:

    private void DataGridCell_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
      DataGridCell cell = sender as DataGridCell;
      GridColumnFastEdit(cell, e);
    }

    private void DataGridCell_PreviewTextInput(object sender, TextCompositionEventArgs e)
    {
      DataGridCell cell = sender as DataGridCell;
      GridColumnFastEdit(cell, e);
    }

    private static void GridColumnFastEdit(DataGridCell cell, RoutedEventArgs e)
    {
      if (cell == null || cell.IsEditing || cell.IsReadOnly)
        return;

      DataGrid dataGrid = FindVisualParent<DataGrid>(cell);
      if (dataGrid == null)
        return;

      if (!cell.IsFocused)
      {
        cell.Focus();
      }

      if (cell.Content is CheckBox)
      {
        if (dataGrid.SelectionUnit != DataGridSelectionUnit.FullRow)
        {
          if (!cell.IsSelected)
            cell.IsSelected = true;
        }
        else
        {
          DataGridRow row = FindVisualParent<DataGridRow>(cell);
          if (row != null && !row.IsSelected)
          {
            row.IsSelected = true;
          }
        }
      }
      else
      {
        ComboBox cb = cell.Content as ComboBox;
        if (cb != null)
        {
          //DataGrid dataGrid = FindVisualParent<DataGrid>(cell);
          dataGrid.BeginEdit(e);
          cell.Dispatcher.Invoke(
           DispatcherPriority.Background,
           new Action(delegate { }));
          cb.IsDropDownOpen = true;
        }
      }
    }


    private static T FindVisualParent<T>(UIElement element) where T : UIElement
    {
      UIElement parent = element;
      while (parent != null)
      {
        T correctlyTyped = parent as T;
        if (correctlyTyped != null)
        {
          return correctlyTyped;
        }

        parent = VisualTreeHelper.GetParent(parent) as UIElement;
      }
      return null;
    }

And in the xaml:

  <UserControl.Resources>
    <Style TargetType="{x:Type DataGridCell}">
      <EventSetter Event="PreviewMouseLeftButtonDown"
                   Handler="DataGridCell_PreviewMouseLeftButtonDown" />
      <EventSetter Event="PreviewTextInput"
                   Handler="DataGridCell_PreviewTextInput" />
    </Style>
  </UserControl.Resources>

That does the trick for me! Found it on StackOverFlow.