Search code examples
c#wpfwpfdatagrid

DataGridTemplateColumn BeginEdit on selection


I subclassed DataGridTemplateColumn to define a custom column type. I use the following code to initialize the edit mode.

    protected override object PrepareCellForEdit(
        FrameworkElement editingElement, RoutedEventArgs editingEventArgs)
    {
        editingElement.MoveFocus(
            new TraversalRequest(FocusNavigationDirection.First));
        return base.PrepareCellForEdit(editingElement, editingEventArgs);
    }

    private void MyTextControlGotFocus(object sender, RoutedEventArgs e)
    {
        var control = sender as MyTextControl;
        if (control != null)
        {
            control.SelectAll();
        }            
    }

The problem is that PrepareCellForEdit gets only called after I 1) clicked into the cell and 2) clicked again to enter edit mode.

With DataGridTextColumn I can select the cell and type in some text to immediately enter edit mode without clicking again. I want the same behaviour for my column type.

The question is, how can I handle a KeyDown event on the cell to call DataGridOwner.BeginEdit in my DataGridTemplateColumn class. I tried to add a PreviewKeyDown handler to the control inside the CellTemplate but the event does not get fired.


Solution

  • I finally came up with this soultion:

    <DataGrid ItemsSource="{Binding Persons}">
      <DataGrid.Columns>
        <DataGridTemplateColumn Header="C1">
          <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
              <TextBlock Text="{Binding Name}"/>
            </DataTemplate>
          </DataGridTemplateColumn.CellTemplate>
          <DataGridTemplateColumn.CellEditingTemplate>
            <DataTemplate>
              <TextBox Text="{Binding Name}" />
            </DataTemplate>
          </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>
      </DataGrid.Columns>
      <DataGrid.CellStyle>
        <Style TargetType="DataGridCell">
          <Setter Property="IsTabStop" Value="False" />
          <Setter Property="Focusable" Value="False" />
          <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
              <Setter Property="IsEditing" Value="True" />
            </Trigger>
          </Style.Triggers>
        </Style>
      </DataGrid.CellStyle>
    </DataGrid>
    

    The important part is Focusable=False (don't know why). Otherwise the IsSelected trigger works only for the first selection.