如何在DataGrid上强制键盘焦点?

时间:2011-08-26 20:08:52

标签: wpf .net-4.0 datagrid expander keyboardfocusmanager

OLD TITLE:GridView SelectCell +焦点/编辑中的不一致动作(GridView重新加载两次?)

我正在开发一个在Expander的Content属性中设置的GridView(由Data绑定)。当我打开扩展器时,我想要第三列,第一个元素被选中并可编辑(但只是集中也可以接受)。当我尝试将此功能添加到附加到Expanded的此操作时,网格从未为我选择第一个项目。我做了一些故障排除,奇怪的是,我发现了一些事情。 Expander是ItemsCollection中模板的一部分,因此每次向此ItemsCollection添加新项目时,都会在屏幕上创建Expander(预设为IsExpanded = false)。我将Debug.WriteLine设置为Expander_Expanded事件,以及DataGrid.Loaded事件,以便在事件发生时告诉我。这是这两个事件的代码。

DataGrid.Loaded:

DataGrid dg = sender as DataGrid;
dg.Focus();
dg.CurrentCell = new DataGridCellInfo(dg.Items[0], dg.Columns[2]);
dg.BeginEdit();

Expander.Expanded:

Expander expander = sender as Expander;
DataGrid dg = expander.Content as DataGrid;
dg.Focus();
dg.CurrentCell = new DataGridCellInfo(dg.Items[0], dg.Columns[2]);
dg.BeginEdit();

当我创建一个包含Expander的项目并且它显示在屏幕上时,会触发DataGrid.Loaded事件。当扩展器第一次扩展时,Expander.Expanded事件以及DataGrid.Loaded将触发。在此之后的每隔一段时间,只会触发Expander.Expanded事件。

第一次,[0] [2]处的单元格被聚焦并处于编辑模式。每隔一次,没有选择/聚焦细胞。如果DataGrid.Loaded事件中没有代码,则无论是第一次打开扩展器,Cell都不会聚焦或处于编辑模式。 Expander.Expanded实际上似乎并没有做任何事情,选择明智。对于记录,DataGrid的绑定工作完美,无论何时进行更改(无论是第一次打开扩展器还是随后的任何时间),数据都会正确更新。谁能解释一下呢?

更新:

经过进一步调查,它与GridLoaded事件没有那么多,因为它与Keyboard.Focus有关。第一次加载DataGrid时,键盘焦点转到Cell(以TextBox的形式)我要求它。但是,每次之后,键盘焦点仍然在打开Expander本身的ToggleButton上。尝试设置Keyboard.Focus(dgCell)或Keyboard.Focus(dg)似乎并没有做任何事情,即使它们都是可聚焦的。我设法通过在打开DataGrid时点击“输入”按钮来验证这个假设。如果DataGrid具有键盘焦点,则enter将移动到下一行。如果ToggleButton具有焦点,它将折叠Expander。

如前所述,第一次打开扩展器时,DataGrid具有键盘焦点,但每隔一段时间,焦点总是以按钮结束。有什么建议吗?

1 个答案:

答案 0 :(得分:3)

我通过调用后来的事件来解决这个问题。使用Expander触发Keyboard.Focus切换到按钮,该按钮在Expanded操作发生后切换扩展器(这使我的焦点切换工作无效)。所以我使用了Expander_SizeChanged并添加了一个检查以确保事件是由Expander开启而不是由窗口本身改变而触发的。在这里设置焦点并选择我想要的Cell。

这是使其工作的代码(expandSomething是在Expander_Expanded事件侦听器上触发的布尔值)。

Expander expander = sender as Expander;
if (expander.IsExpanded && expandSomething)
{
    expandSomething = false;
    DataGrid dg = expander.Content as DataGrid;
    dg.Focus();
    if (dg.SelectedCells.Count == 0)
    {
        dg.CurrentCell = new DataGridCellInfo(dg.Items[0], dg.Columns[2]);
        dg.SelectedCells.Add(dg.CurrentCell);
    }
    else
    {
        dg.CurrentCell = dg.SelectedCells[0];
    }
}