如何强制键盘聚焦在 DataGrid 上?
旧标题:GridView SelectCell + 焦点/编辑中的操作不一致(GridView 重新加载两次?)
我正在开发一个在 Expander 的 Content 属性中设置的 GridView(由数据绑定)。当我打开扩展器时,我希望选择第三列、第一个元素并进行编辑(但简单地聚焦也是可以接受的)。当我尝试将此功能添加到附加到 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 事件中没有代码,则无论是否第一次打开 Expander,单元格都不会获得焦点或处于编辑模式。 Expander.Expanded 实际上似乎并没有在选择方面做任何事情。根据记录,DataGrid 的绑定工作完美,无论我何时进行更改(无论是第一次打开 Expander 还是随后的任何时候),数据都会正确更新。谁能解释一下吗?
更新:
经过进一步调查,它与 GridLoaded 事件的关系不如与 Keyboard.Focus 的关系大。第一次加载 DataGrid 时,键盘焦点转到我要求的单元格(以文本框的形式)。然而,此后每次,键盘焦点仍然位于打开 Expander 本身的 ToggleButton 上。尝试设置 Keyboard.Focus(dgCell) 或 Keyboard.Focus(dg) 似乎没有做任何事情,即使它们都是可聚焦的。我通过在打开 DataGrid 时点击“输入”按钮来验证这个假设。如果 DataGrid 有键盘焦点,则 Enter 将移动到下一行。如果 ToggleButton 获得焦点,它将折叠 Expander。
如前所述,第一次打开 Expander 时,DataGrid 具有键盘焦点,但每隔一次,焦点总是以按钮结束。有什么建议吗?
OLD TITLE: Inconsistent Actions in GridView SelectCell + Focus/Edit (GridView Reloaded Twice?)
I'm developing a GridView (bound by Data) set in the Content property of an Expander. When I open the Expander, I want the third column, first element to be selected and editable (but simply focused would be acceptable as well). When I tried to add this functionality to this action attached to Expanded, the grid never selected the first item for me. I did some troubleshooting, and strangely enough, I noticed something occurring. The Expander is part of a template within an ItemsCollection, so every time I add a new item to this ItemsCollection, an Expander is created on the screen (preset to IsExpanded = false). I set a Debug.WriteLine to the Expander_Expanded event, and the DataGrid.Loaded event as well, to let me know when the events were occurring. Here's the code for both of those events.
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();
When I create an item that contains the Expander and it is shown on the screen, the DataGrid.Loaded event fires. When the expander is expanded for the first time, the Expander.Expanded event fires, as well as the DataGrid.Loaded. Every other time after that, only the Expander.Expanded event fires.
The first time, the Cell at [0][2] is focused and in edit mode. Every other time, no cells are selected/focused. If there's no code in the DataGrid.Loaded event, then the Cell will not be focused or in edit mode regardless if it's the first time the Expander is opened or not. Expander.Expanded doesn't actually seem to do anything though, selection-wise. For the record, the bindings for DataGrid work perfectly, and no matter when I make changes (whether it's the first time the Expander opens or any times subsequently), the data updates properly. Can anyone explain this?
UPDATE:
After further investigation, it doesn't have as much to do with the GridLoaded event as it has to do with the Keyboard.Focus. The first time the DataGrid is loaded, the keyboard focus goes to the Cell (in the form of a TextBox) I ask it to. However, every time after that, the keyboard focus is still on the ToggleButton that opens the Expander itself. Trying to set Keyboard.Focus(dgCell) or Keyboard.Focus(dg) doesn't seem to do anything though, even if they're both focusable. I managed to validate this assumption by hitting the "enter" button when the DataGrid is opened. If the DataGrid has keyboard focus, enter will move to the next row. If the ToggleButton has the focus, it will collapse the Expander.
As noted before, the first time the Expander is opened, the DataGrid has Keyboard focus, but every other time, the focus always ends up with the button. Any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我通过调用稍后的事件解决了这个问题。使用扩展器触发了 Keyboard.Focus 切换到在扩展操作发生后切换扩展器的按钮(这使我的焦点切换工作无效)。因此,我使用 Expander_SizeChanged 并添加了一项检查,以确保该事件是由 Expander 打开而不是由窗口本身更改触发的。将焦点设置在这里并选择我想要解决的单元格。
下面是使其工作的代码(expandSomething 是在 Expander_Expanded 事件侦听器上触发的布尔值)。
I solved this by calling a later event. Using an Expander triggered a Keyboard.Focus switch to the button that toggles the expander after the Expanded operation happens (which nullified my focus switching work). So I used Expander_SizeChanged and added a check to make sure the event was triggered by a Expander opening and not by the window itself changing. Setting the focus here and selecting the Cell I wanted worked out.
Here's the code that made it work (expandSomething is a boolean triggered on the Expander_Expanded event listener).