另一个datagrid键绑定问题
我有一个数据网格。它的选择模式设置为FullRow和KeyboardNavigation.TabNavigation =“Once”,我希望得到我想要的结果,但事实并非如此。
当数据网格具有焦点时按下Tab键,它将逐个选中网格中的每一列。因此,如果我选中具有4列的网格,我将不得不按Tab键4次以转到下一个tabindex。
我想要的是第一次按下时tab键从数据网格中直接标签,并将焦点放在下一个tabindex ...如果这是有意义的。
我试过覆盖keydown事件处理程序中的tab键,如此。
class BetterDataGrid : DataGrid
{
..............
protected override void OnKeyDown(System.Windows.Input.KeyEventArgs e)
{
..............
if (e.Key == Key.Tab)
{
Console.WriteLine("TAB");
MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
}
.........
}
它确实将“TAB”写入控制台,但该选项卡仍然保持默认行为。不确定这是否是下一个tabindex的正确方法,但是这应该使tab键除了写入控制台或引起异常外什么都不做。
让我觉得不可能覆盖tab键行为。
希望得到一些有用的意见 一如既往,提前谢谢。
答案 0 :(得分:9)
我想要这个用于我的业务线软件,我发现解决它的唯一方法是使用datagrid的PreviewKeyDown,GotKeyboardFocus和LostKeyboardFocus事件进行代码隐藏。我已将这些事件处理程序放在WPF装饰器中,以避免为每个DataGrid重复它。可能有可能将DataGrid子类化,但我还没有尝试过。
处理程序的代码如下(DataGrid是x:Name =" grid"对于此示例代码):
private IInputElement lastDataGridFocus = null;
private int selectedcolumnindex = 0;
void grid_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
if (grid.Items.Count > 0 && (e.NewFocus is DataGrid || (e.NewFocus is DataGridCell && !(e.OldFocus is DataGridCell))))
{
DataGridCell cell = null;
if (lastDataGridFocus != null)
{
FocusManager.SetFocusedElement(grid, lastDataGridFocus);
lastDataGridFocus = null;
e.Handled = true;
return;
}
if (grid.SelectedCells.Count == 0)
{
DataGridRow rowContainer = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(0);
if (rowContainer != null)
{
DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);
cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex((selectedcolumnindex < 0) ? 0 : selectedcolumnindex);
}
}
else
{
DataGridCellInfo selectedDataGridCellInfo = (grid.SelectedCells[0] as DataGridCellInfo?).Value;
DataGridRow rowContainer = (DataGridRow)grid.ItemContainerGenerator.ContainerFromItem(selectedDataGridCellInfo.Item);
if (rowContainer != null)
{
DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);
cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex((selectedcolumnindex < 0) ? 0 : selectedcolumnindex);
}
}
if (null != cell)
{
FocusManager.SetFocusedElement(grid, cell as IInputElement);
e.Handled = true;
}
}
}
void grid_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
if (!(e.NewFocus is DataGridCell))
{
if (grid.CurrentCell != null)
{
selectedcolumnindex = grid.Columns.IndexOf(grid.CurrentCell.Column);
}
}
}
void grid_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (Keyboard.Modifiers == ModifierKeys.Shift && e.Key == Key.Tab)
{
lastDataGridFocus = Keyboard.FocusedElement;
grid.MoveFocus(new TraversalRequest(FocusNavigationDirection.Previous));
e.Handled = true;
}
else if (Keyboard.Modifiers == ModifierKeys.None && e.Key == Key.Tab)
{
lastDataGridFocus = Keyboard.FocusedElement;
grid.MoveFocus(new TraversalRequest(FocusNavigationDirection.Last));
(Keyboard.FocusedElement as FrameworkElement).MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
e.Handled = true;
}
}
使用此代码,您可以使用光标键在网格内导航,并使用Tab键和shift-tab键将您从数据网格中移出。如果您退出网格并返回网格,您也会进入您离开的同一个单元格。这是我的用户和我想要的,这是IMHO DataGrid控件应该提供的默认行为。
答案 1 :(得分:-2)
你想要实现的不是正确的行为,当DataGrid聚焦时,每个人都希望在按Tab键时像Excel一样导航。如果您不希望用户在DataGrid中导航,最好通过在DataGrid上设置IsTabStop="False"
来阻止DataGrid上的制表位。