Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get datagrid's scrollviewer

Tags:

c#

wpf

datagrid

I'm trying to get the datagrid's scrollviewer to be able to set the offset (which has been stored earlier).

I use this function :

public static T GetVisualChild<T>(DependencyObject parent) where T : Visual       
{     
    T child = default(T);

    int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
    for (int i = 0; i < numVisuals; i++)
    {
        Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
        child = v as T;
        if (child == null)
        {
            child = GetVisualChild<T>(v);
        }
        if (child != null)
        {
            break;
        }
    }
    return child;
}

And I call it like this :

this.dataGrid.ItemsSource = _myData;
ScrollViewer sc = ressource_design.GetVisualChild<ScrollViewer>(this.dataGrid);
if (sc != null) sc.ScrollToVerticalOffset(stateDatagrid.ScrollbarOffset);

And it works in many cases, but in some cases the function returns null and I'm not able to get the scrollviewer.

This call is made just after setting the ItemsSource (ObservableCollection of items) and it works well in 90% cases. The datagrid has not been rendered yet.

I've also tried with the function :

public static ScrollViewer GetScrollViewerFromDataGrid(DataGrid dataGrid)       
{        
    ScrollViewer retour = null;
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dataGrid) && retour == null; i++)
    {
        if (VisualTreeHelper.GetChild(dataGrid, i) is ScrollViewer)
        {

            retour = (ScrollViewer)(VisualTreeHelper.GetChild(dataGrid, i));

        }
    }
    return retour;
}

still null.

Why I'm unable to get the datagrid's scrollviewer ?

I've not pasted my datagrid's style since I have datagrids working with it and it is complicated with many dependencies.

I thought it could be related to virtualization but i'm not able to retrieve the scrollviewer of this datagrid :

<DataGrid Style="{StaticResource StyleDataGrid}"  HeadersVisibility="None" ItemsSource="{Binding _Data}" Name="dataGrid1" RowDetailsVisibilityMode="Visible"  SelectionChanged="dataGrid1_SelectionChanged">
like image 585
user2088807 Avatar asked Dec 14 '16 00:12

user2088807


1 Answers

You need to go recursive through the VisualTree elements. Your function only looks at DataGrid layer. If the ScrollViewer isn't there (see picture) you will not find it.

enter image description here

Try the following function:

public static ScrollViewer GetScrollViewer(UIElement element)
{
    if (element == null) return null;

    ScrollViewer retour = null;
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element) && retour == null; i++) {
        if (VisualTreeHelper.GetChild(element, i) is ScrollViewer) {
            retour = (ScrollViewer) (VisualTreeHelper.GetChild(element, i));
        }
        else {
            retour = GetScrollViewer(VisualTreeHelper.GetChild(element, i) as UIElement);
        }
    }
    return retour;
}
like image 99
WPFGermany Avatar answered Nov 03 '22 21:11

WPFGermany