Редактирование столбца WPF datagridcombobox при нажатии клавиши

#wpf #combobox #datagrid #keypress

#wpf #combobox #datagrid #нажатие клавиши

Вопрос:

У меня есть datagrid с a DataGridComboBoxColumn в нем.

Я хочу, чтобы мои пользователи могли войти в режим редактирования, просто набрав текст.
Это поведение по умолчанию DataGridTextColumn , и мне не нравится, что им приходится нажимать F2, чтобы включить редактирование только для этого типа столбца.

Как я могу DataGridComboBoxColumn перейти в режим редактирования без необходимости нажимать клавишу F2? В идеале при нажатии клавиши, но я был бы в порядке, если бы он также вошел в режим редактирования при фокусировке.

Изменения решения в принятом ответе, которые возвращают базовую функциональность datagrid:

  void Cell_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        if(e.Key == Key.Enter || e.Key == Key.Tab)
        {
            dgBins.CommitEdit();
            dgBins.SelectedIndex  = 1;
        }else if(e.Key.ToString().Length == 1 
            || (e.Key.ToString().StartsWith("D") amp;amp; e.Key.ToString().Length == 2)
            || e.Key.ToString().StartsWith("NumPad")
            || e.Key == Key.Delete 
            || e.Key == Key.Back )
        { 
            if (e.OriginalSource is DataGridCell)
            {
                DataGridCell cell = (sender as DataGridCell);
                Control elem = FindChild<Control>(cell, null);
                elem.Focus();
            }
        }
    }
  

Ответ №1:

     <DataGrid.CellStyle>
         <Style TargetType="DataGridCell">
             <EventSetter Event="PreviewKeyDown" Handler="Cell_PreviewKeyDown"/>
             <EventSetter Event="GotFocus" Handler="Cell_GotFocus"/>
         </Style>
    </DataGrid.CellStyle>
  

Обработчики :

 void Cell_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.OriginalSource is DataGridCell)
    {
        DataGridCell cell = (sender as DataGridCell);
        Control elem = FindChild<Control>(cell, null);
        elem.Focus();
    }
}

void Cell_GotFocus(object sender, RoutedEventArgs e)
{
    DataGridCell cell = (sender as DataGridCell);
    cell.IsEditing = true;
}
  

Помощник :

 public static T FindChild<T>(DependencyObject parent, string childName)
        where T : DependencyObject
{
    // Confirm parent and childName are valid. 
    if (parent == null) return null;

    T foundChild = null;

    int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
    for (int i = 0; i < childrenCount; i  )
    {
        var child = VisualTreeHelper.GetChild(parent, i);
        // If the child is not of the request child type child
        T childType = child as T;
        if (childType == null)
        {
            // recursively drill down the tree
            foundChild = FindChild<T>(child, childName);

            // If the child is found, break so we do not overwrite the found child. 
            if (foundChild != null) break;
        }
        else if (!string.IsNullOrEmpty(childName))
        {
            var frameworkElement = child as FrameworkElement;
            // If the child's name is set for search
            if (frameworkElement != null amp;amp; frameworkElement.Name == childName)
            {
                // if the child's name is of the request name
                foundChild = (T)child;
                break;
            }
        }
        else
        {
            // child element found.
            foundChild = (T)child;
            break;
        }
    }

    return foundChild;
}
  

Если это решит вашу проблему.

Комментарии:

1. Это почти работает, мне пришлось изменить его так, чтобы он игнорировал клавиши enter, escape и tab. Кроме того, теперь пользователь должен дважды нажать enter, чтобы перейти к следующей строке … пытаясь выяснить, как это остановить.

2. @MrZander Это кандидат на отдельный вопрос. Поэтому прошу вас задать вопрос отдельно. И если это ответ на ваш текущий вопрос, отметьте его соответствующим образом.

3. Конечно, это приводит к переходу в режим редактирования, но это нарушает практически все другие функции datagrid. Не идеально. Во всяком случае, я обновил вопрос своими изменениями, которые устраняют проблему.

4. @MrZander Если вы попытаетесь изменить поведение по умолчанию чрезвычайно сложного элемента управления, такого как DataGrid, то вам придется сделать очень много вещей.

Ответ №2:

Вы можете попробовать использовать SelectedCellsChanged событие. Он работает при изменении фокуса.

Если вы не хотите такого поведения в других столбцах, вы можете проверить e.AddedCells[0].Column свойство (если оно у вас SelectionUnit="Cell" DataGrid есть ).

 private void dgTest_SelectedCellsChanged( object sender, SelectedCellsChangedEventArgs e )
{
    ( sender as DataGrid ).BeginEdit();
}
  

Ответ №3:

Мой ответ может быть немного запоздалым, но я хочу добавить это, потому что ни один данный ответ не решал проблему для меня, не нарушая обычную обработку клавиатуры DataGrid.

Вопрос прост:

Я хочу, чтобы мои пользователи могли войти в режим редактирования, просто набрав текст.

Таково решение:

 <DataGrid KeyDown="DataGrid_KeyDown">
    ...
</DataGrid>
  

С кодом в коде за xaml.cs:

 private void DataGrid_KeyDown(object sender, KeyEventArgs e)
{
    DataGrid dg = (sender as DataGrid);
    if (dg.CurrentColumn is DataGridComboBoxColumn)
    {
        dg.BeginEdit();
    }
}
  

Поскольку это уже нормальное поведение текстовых полей, я только хотел применить это к DataGridComboBoxColumn. Конечно, это будет вызываться при каждом нажатии клавиши, но вызов ‘BeginEdit’, похоже, не повредит, когда DataGrid уже находится в режиме редактирования.