UWP DataGrid Horizontal Scrollbar overlaps DataGrid Content

Eckart Schlottmann 21 Reputation points
2020-08-27T21:49:16.297+00:00

I am using the community toolkit DataGrid and the data presented to the user requires a horizontal (and vertical) scrollbar.
When using the keyboard and pressing cursor down at some point in time the scrolling of the content starts and renders the selected line behind the semi-transparent horizontal scrollbar.

The problem is that this selected line is not really readable due to the overlapping scroll bar.

20944-anmerkung-2020-08-27-234256.png

How is it possible to disable the transparency of the scrollbar and to allow the scrollbar to use real space that is not shared with DataGrid content? I am trying to get the classical scrollbar behavior.

Developer technologies | Universal Windows Platform (UWP)
0 comments No comments
{count} votes

Accepted answer
  1. Richard Zhang-MSFT 6,936 Reputation points Microsoft Employee Moderator
    2020-08-28T01:51:28.917+00:00

    Hello,

    Welcome to Microsoft Q&A.

    About the default template definition of DataGrid, you can see here.

    Can briefly describe the reasons:

    • In DataGrid, ScrollViewer is not used, but ScrollBar is used directly.
    • The main content display area is a Grid, which defines three rows. The row display area (DataGridRowsPresenter) is in the second row and spans two rows, and the horizontal scroll bar is in the third row. This is why the horizontal scroll bar covering the row area.

    In this way, there is no direct way to achieve your needs. If you want to separate ScrollBar and DataGridRowsPresenter, you can consider using ViusalTreeHelper.

    public static T VisualTreeFind<T>(this DependencyObject element)
        where T : DependencyObject
    {
        T retValue = null;
        var childrenCount = VisualTreeHelper.GetChildrenCount(element);
        for (var i = 0; i < childrenCount; i++)
        {
            var child = VisualTreeHelper.GetChild(element, i);
            var type = child as T;
            if (type != null)
            {
                retValue = type;
                break;
            }
            retValue = VisualTreeFind<T>(child);
            if (retValue != null)
            {
                break;
            }
        }
        return retValue;
    }
    

    Usage

    private void dataGrid_Loaded(object sender, RoutedEventArgs e)
    {
        var rowsPre = dataGrid.VisualTreeFind<DataGridRowsPresenter>();
        Grid.SetRowSpan(rowsPre, 1);
    }
    

    Because it is set by looking for VisualTree, it must be done after the DataGrid is loaded, which is why this method is called in the DataGrid.Loaded event.

    By limiting the DataGridRowsPresenter to the second row and the HorizontalScrollBar in the third row, the two elements are separated to avoid content occlusion.

    Thanks.


1 additional answer

Sort by: Most helpful
  1. Eckart Schlottmann 21 Reputation points
    2020-08-28T21:29:38.457+00:00

    Dear Richard,

    thank You very much. This works great for the moment and I am very pleased that You could help me.

    I will propose a clean API for the same as a feature request to the WindowsCommunityToolkit development since with this solution there is no guarantee for future fitness.

    Greetings
    Eckart

    --> Link to feature request (yes...it really got this nice number...):
    3456

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.