C# wpfdatagrid和tab键

C# wpfdatagrid和tab键,c#,wpf,datagrid,key-bindings,C#,Wpf,Datagrid,Key Bindings,另一个datagrid键绑定问题 我有一个数据网格。它的选择模式设置为FullRow和KeyboardNavigation.TabNavigation=“Once”,我希望它能得到我想要的结果,但它没有 当datagrid具有焦点时按下tab键,它将逐个在网格中的每一列上进行tab。因此,如果我在有4列的网格中使用tab键,我必须按tab键4次才能转到下一个tabindex 我想要的是tab键在第一次按下时直接从datagrid中移出,并将焦点放在下一个tabindex上。。。如果这有道理的话

另一个datagrid键绑定问题

我有一个数据网格。它的选择模式设置为FullRow和KeyboardNavigation.TabNavigation=“Once”,我希望它能得到我想要的结果,但它没有

当datagrid具有焦点时按下tab键,它将逐个在网格中的每一列上进行tab。因此,如果我在有4列的网格中使用tab键,我必须按tab键4次才能转到下一个tabindex

我想要的是tab键在第一次按下时直接从datagrid中移出,并将焦点放在下一个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键的行为

希望得到一些有用的信息。

一如既往,请提前感谢。

您试图实现的不是正确的行为,每个人都希望在DataGrid处于焦点状态时按Tab键时获得类似Excel的导航。如果您不希望用户在DataGrid中导航,最好通过在DataGrid上设置
IsTabStop=“False”
来防止DataGrid上的制表位停止。

我希望将此用于我的业务线软件,我发现解决此问题的唯一方法是使用PreviewKeyDown,datagrid的GotKeyboardFocus和LostKeyboardFocus事件。我将这些事件处理程序放在WPF装饰器中,以避免对每个DataGrid重复它。也许可以将DataGrid子类化,但我还没有尝试过

处理程序的代码如下(此示例代码的DataGrid为x:Name=“grid”):

private IInputElement lastDataGridFocus=null;
private int selectedcolumnindex=0;
void grid_GotKeyboardFocus(对象发送器,KeyboardFocusChangedEventArgs e)
{
如果(grid.Items.Count>0&&(e.NewFocus是DataGrid | | |(e.NewFocus是DataGridCell&&!(e.OldFocus是DataGridCell)))
{
DataGridCell=null;
if(lastDataGridFocus!=null)
{
SetFocusedElement(网格,lastDataGridFocus);
lastDataGridFocus=null;
e、 已处理=正确;
返回;
}
if(grid.SelectedCells.Count==0)
{
DataGridRow rowContainer=(DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(0);
if(rowContainer!=null)
{
DataGridCellsPresenter=GetVisualChild(行容器);
单元格=(DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex((selectedcolumnindex<0)?0:selectedcolumnindex);
}
}
其他的
{
DataGridCellInfo selectedDataGridCellInfo=(grid.SelectedCells[0]作为DataGridCellInfo?).Value;
DataGridRow rowContainer=(DataGridRow)grid.ItemContainerGenerator.ContainerFromItem(selectedDataGridCellInfo.Item);
if(rowContainer!=null)
{
DataGridCellsPresenter=GetVisualChild(行容器);
单元格=(DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex((selectedcolumnindex<0)?0:selectedcolumnindex);
}
}
如果(空!=单元格)
{
SetFocusedElement(网格,单元格作为IIInputElement);
e、 已处理=正确;
}
}
}
无效网格\u丢失键盘焦点(对象发送器,键盘焦点更改Deventargs e)
{
如果(!(例如,NewFocus是DataGridCell))
{
if(grid.CurrentCell!=null)
{
selectedcolumnindex=grid.Columns.IndexOf(grid.CurrentCell.Column);
}
}
}
void grid_PreviewKeyDown(对象发送方,KeyEventArgs e)
{
if(Keyboard.Modifiers==ModifierKeys.Shift&e.Key==Key.Tab)
{
lastDataGridFocus=Keyboard.FocusedElement;
MoveFocus(新的遍历请求(FocusNavigationDirection.Previous));
e、 已处理=正确;
}
else if(Keyboard.Modifiers==ModifierKeys.None&&e.Key==Key.Tab)
{
lastDataGridFocus=Keyboard.FocusedElement;
MoveFocus(新的遍历请求(FocusNavigationDirection.Last));
(Keyboard.FocusedElement作为FrameworkElement)、MoveFocus(新的遍历请求(FocusNavigationDirection.Next));
e、 已处理=正确;
}
}

使用这段代码,您可以使用光标键在网格内导航,而tab键和shift-tab键将您带出数据网格。如果您将标签从网格中移出并返回网格,那么您也将到达您离开的同一单元格。这就是我和我的用户想要的,这也是DataGrid控件应该提供的默认行为。

为什么要投反对票?!从用户体验的角度来看,这只是我的观点!!是的,我同意你的看法,法迪尔先生,最好设置IsTabStop=“False”对不起,你的回答根本没有帮助。IsTabStop=false将tabing移到网格中,我希望保留它,当它聚焦时不会产生期望的行为。当然,在很多情况下,Excel风格的导航效果很好,但在这种情况下,它只是多余的,网格是只读的,并且有完整的行选择。如果它是只读的
DataGrid
,我很难理解制表符停止的意义…@Hohinhime。在DataGrid中使用tab键,然后使用箭头键在DataGrid中导航,当您想要离开DataGrid时,再次使用tab键。我认为这是最好的办法。如果
        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;
        }
    }