How to Force Keyboard Focus on a 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?
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).
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];
}
}
精彩评论