WPF DataGrid - Setting Focus To A Specific Cell

Mar 13, 2009 at 11:35 PM

Hello,

I would like to do the following in my code to get the focus moved to a specific cell.

var request = new TraversalRequest(FocusNavigationDirection.Next) { Wrapped = true };

cell.MoveFocus(request);

However, how do I get cell as a DataGridCell in a straighforward fashion? Without say having to resort to ItemContainerGenerator.ContainerFromIndex calls and a GetVisualChild<DataGridCellsPresenter> tree traversal method. This typically gives a null reference exception; something to do with virtualization?

I have both the row and column index from knowning which cell a user has just selected and edited. This is to move the focus to the next cell after the edited changes are committed and the datagrid refreshed, dataGrid.Items.Refresh(), in order to update the changes visually.

Just wish it was a simple as dataGrid.SelectCell(x, y).

Many thanks,

Gavin

Mar 16, 2009 at 5:04 PM
I'm having the same issue.  I want to grab a cell based on x,y grid position (I want to specify a cell to focus).

Anyone?

Dave
Coordinator
Mar 17, 2009 at 1:44 AM
I'm afraid that what you've described is all that's available.

Exposing an API like GetCell(x, y) was discussed. Just as you encountered issues with virtualization, so would this API. At that point, does the API return null or does it try to cause the container to be generated? If it returns null, it may not be clear why the return value is null at one point and non-null at another. If it generates the container, that may cause the grid to scroll unexpectedly. It could also lead a developer to instantiate all the cells in the grid.

I would be curious to know anyone's views on this issue as we've internally debated this before and ultimately did nothing, but we're also asked for this functionality a lot too.

Thanks,
Ben
Mar 17, 2009 at 3:32 PM
From my standpoint it makes it difficult to work with the DataGrid in an extended fashion without a lot of work and headaches. If I'm getting users to enter data then refreshing the grid and dependent properties on-the-fly and we cannot reset the focus in a useful way then it seriously limits what we want to acheive.
Mar 17, 2009 at 5:04 PM
I agree with Gavin, in my opinion this functionality should be added.  Whatever your implementation, it would be better than possible workarounds anyone else comes up with.  As to the question of if the API should return null or try to cause the container to be generated, I would say definitely generate the container.  If it didn't do that it would cause a lot of confusion and be a lot less useful.  I'm not sure what I would do with a null value for a cell I know exists.  If someone ran into performance problems because they were looping over every cell in the grid, hopefully the first thing they would look at is the fact that they're touching every cell in the grid, but a slow app is better than no app.  You could even note the performance penalty in the help for GetCell().

This function should just do the default of what a developer expects, simply return the Cell in the grid (virtualization should be behind the scenes at this point), and of course prevent the grid from scrolling unexpectedly.  I expect this function would be widely used.

Dave
Mar 17, 2009 at 11:05 PM
Specifics of the problem I'm experiencing can be found in the discussion

http://wpf.codeplex.com/Thread/View.aspx?ThreadId=34065

I've included a link to this to illustrate what is involved.
Coordinator
Mar 17, 2009 at 11:25 PM
Thank you for the feeback, and please continue to comment as this is all very valuable in designing the controls and framework. To set some expectation, though, we could implement a GetCell that does not automatically generate elements in the Toolkit version of DataGrid, but to achieve the automatically generating version would require some design changes in WPF. The generator, the ItemsControl, and the Panel are all involved with container generation, but it is the Panel that causes generation and holds onto the containers in the visual tree, not the ItemsControl. There is no general interface between the ItemsControl and the Panel to cause container generation at present, which is what would need to happen for the DataGrid to cause the desired row and cell to be generated. We could put in some internal methods to DataGridRowsPresenter and DataGridCellsPresenter/Panel to accomplish that in the default case, but generally we don't like going that route (though we have done it for other things) since once you change the ItemsPanel, GetCell would no longer work at all.

Ben