#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 уже находится в режиме редактирования.