WPF DataGrid - How to stay focused on the bottom of the DataGrid as new rows are added?
Solution 1
Looks like DataGrid.ScrollIntoView(<item>)
will keep the focus on the bottom of the DataGrid
.
Solution 2
This is a simple approach using LoadingRow event:
void dataGrid_LoadingRow(object sender, System.Windows.Controls.DataGridRowEventArgs e)
{
dataGrid.ScrollIntoView(e.Row.Item);
}
Just remember to disable it after the grid loading is finished.
Solution 3
I've found that the most useful time to call the ScrollIntoView method is from the ScrollViewer.ScrollChanged attached event. This can be set in XAML as follows:
<DataGrid
...
ScrollViewer.ScrollChanged="control_ScrollChanged">
The ScrollChangedEventArgs object has various properties that can be helpful for computing layout and scroll position (Extent, Offset, Viewport). Note that these are typically measured in numbers of rows/columns when using the default DataGrid virtualization settings.
Here's an example implementation that keeps the bottom item in view as new items are added to the DataGrid, unless the user moves the scrollbar to view items higher up in the grid.
private void control_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
// If the entire contents fit on the screen, ignore this event
if (e.ExtentHeight < e.ViewportHeight)
return;
// If no items are available to display, ignore this event
if (this.Items.Count <= 0)
return;
// If the ExtentHeight and ViewportHeight haven't changed, ignore this event
if (e.ExtentHeightChange == 0.0 && e.ViewportHeightChange == 0.0)
return;
// If we were close to the bottom when a new item appeared,
// scroll the new item into view. We pick a threshold of 5
// items since issues were seen when resizing the window with
// smaller threshold values.
var oldExtentHeight = e.ExtentHeight - e.ExtentHeightChange;
var oldVerticalOffset = e.VerticalOffset - e.VerticalChange;
var oldViewportHeight = e.ViewportHeight - e.ViewportHeightChange;
if (oldVerticalOffset + oldViewportHeight + 5 >= oldExtentHeight)
this.ScrollIntoView(this.Items[this.Items.Count - 1]);
}
Taylor Leese
I herd cats and make services scale -- sometimes at the same time.
Updated on June 09, 2022Comments
-
Taylor Leese almost 2 years
I am using
DataGrid
from the WPF Toolkit and I need to be able to maintain focus on the bottom of the grid (i.e. the last row). The problem I'm having right now is that as rows are added the scrollbar for theDataGrid
doesn't scroll along with the new rows being added. What's the best way to accomplish this? -
joe over 14 yearsWhere do you call this method?
-
Vinzz over 14 yearsit does. Just make a call after you have updated your datasource with the new element. Be sure to call UpdateLayout() before ScrollIntoView though!
-
Taylor Leese over 14 yearsWhy do you need to call UpdateLayout() first? I didn't have to do that. Is it just a best practice for some reason?