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 the DataGrid
doesn't scroll along with the new rows being added. What's the best way to accomplish this?
Looks like DataGrid.ScrollIntoView(<item>)
will keep the focus on the bottom of the DataGrid
.
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.
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]);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With