Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF DataGrid - How to stay focused on the bottom of the DataGrid as new rows are added?

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?

like image 385
Taylor Leese Avatar asked Aug 18 '09 22:08

Taylor Leese


3 Answers

Looks like DataGrid.ScrollIntoView(<item>) will keep the focus on the bottom of the DataGrid.

like image 200
Taylor Leese Avatar answered Nov 10 '22 09:11

Taylor Leese


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.

like image 22
babakansari Avatar answered Nov 10 '22 09:11

babakansari


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]);
    }
like image 5
Matt Avatar answered Nov 10 '22 10:11

Matt