我想在我的数据网格中自动选择我的第一个项目(当我的表单加载时)
这是我的代码
myDataGridEvtCode.Focus();
myDataGridEvtCode.SelectedIndex = 0;
我的问题是,如果我使用箭头(向下),行不会改变,我需要输入 3 次才能更改选定的行。我认为这是因为我的 SelectedItem 注意力不集中。
非常感谢 :)
我想在我的数据网格中自动选择我的第一个项目(当我的表单加载时)
这是我的代码
myDataGridEvtCode.Focus();
myDataGridEvtCode.SelectedIndex = 0;
我的问题是,如果我使用箭头(向下),行不会改变,我需要输入 3 次才能更改选定的行。我认为这是因为我的 SelectedItem 注意力不集中。
非常感谢 :)
我从各种资源中收集了针对 DataGrid 行键盘的信息,最后我的解决方案如下所示:
public void SelectRow(DataGrid grid, int rowIndex)
{
grid.SelectedItem = null;
object item = grid.Items[rowIndex];
grid.SelectedItem = item;
var row = grid.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;
if (row == null)
{
grid.ScrollIntoView(item);
row = grid.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;
}
if (row != null)
{
row.Focus();
FocusManager.SetIsFocusScope(row, true);
FocusManager.SetFocusedElement(row, row);
}
}
此外,当我们尝试使用箭头键将焦点从所选项目行移动到下一行时,DataGrid 键盘行为存在一个小错误。它在第一次按键时将焦点从行容器移动到当前行(这很奇怪,因为焦点在某种程度上不在 SelectRow 方法中选择的选定行项上)。
我找到了一个解决方案,并根据我的目的对其进行了修改。
这是一个解释,如何修复这个错误。
基于它,这是我的实现:
private void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
{
if (grid.ItemContainerGenerator.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
{
int index = grid.SelectedIndex;
if (index >= 0)
{
var row = grid.ItemContainerGenerator.ContainerFromIndex(index) as DataGridRow;
if (row != null)
{
row.Focus();
var presenter = FindVisualChild<DataGridCellsPresenter>(row);
var cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(0);
cell.Focus();
FocusManager.SetIsFocusScope(row, true);
FocusManager.SetFocusedElement(cell, cell);
}
}
}
}
public static TChildItem FindVisualChild<TChildItem>(DependencyObject obj) where TChildItem : DependencyObject
{
for (int i = 0; i < System.Windows.Media.VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = System.Windows.Media.VisualTreeHelper.GetChild(obj, i);
if (child is TChildItem)
return (TChildItem)child;
var childOfChild = FindVisualChild<TChildItem>(child);
if (childOfChild != null)
return childOfChild;
}
return null;
}
并订阅构造函数中的事件:
grid.ItemContainerGenerator.StatusChanged += ItemContainerGenerator_StatusChanged;
我希望它能帮助某人解决这个问题。
WPF中有多种类型的焦点,包括逻辑焦点和键盘焦点。在我看来,所选行正在接收逻辑焦点而不是键盘焦点。您可以使用以下设置键盘焦点:
Keyboard.Focus(elementToFocus);
然而,根据我的经验,Focus 可能会变得非常复杂。它通常需要涉及FocusManager
,尤其是在非平凡的场景中。
我建议阅读 WPF Focus并摆弄Keyboard
andFocusManager
对象,直到你让它以你想要的方式运行。