Skip to content

ScrollViewer Position on DataGrid under .NET 9 Fluent Style resets position after loading again #10962

@kaijauk

Description

@kaijauk

Description

I have noticed a weird behavior with DataGrid and the Fluent Style provided with NET 9.0.

Scenario:
I have a TabView that caches all the content from the children so they don't loose ScrollViewer Position e.g. when switching between tabs.
However, if I place a DataGrid inside and scroll down, switch back and forth between the tabs, the scroll position will be reset to the top.
If I use a custom DataGrid control and overwrite the style back to a blank one, this behavior does not occur and the position stays where it was.

Reproduction Steps

Note: TestItems has 1000 Elements.

"Resetting" DataGrid (with style from Fluent.xaml)

<DataGrid ItemsSource="{Binding TestItems}"
                  Height="800"
                  Width="800"/>

Behaves as expected (ScrollViewer stays at the previous position):

<DataGrid ItemsSource="{Binding TestItems}"
                  Height="800"
                  Width="800">
    <DataGrid.Style>
            <Style TargetType="DataGrid" />
    </DataGrid.Style>
</DataGrid>

Expected behavior

ScrollViewer should keep it's position after changing between Tabs when the Content is cached

Actual behavior

ScrollViewer resets scrolling position back to the top.

Known Workarounds

For now: not use the Fluent.xaml DataGrid Style

It might be due to putting the Template into a custom Scroll Viewer to achieve the rounded Borders.
That's from the Fluent.Light.XAML, starting at line 2305 for the DefaultDataGridStyle

 <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="{x:Type DataGrid}">
          <Border x:Name="border" Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding Border.CornerRadius}" SnapsToDevicePixels="True">
            <ScrollViewer x:Name="DG_ScrollViewer" Focusable="False">
              <ScrollViewer.Template>
                <ControlTemplate TargetType="{x:Type ScrollViewer}">
                  <Grid>
                    <Grid.ColumnDefinitions>
                      <ColumnDefinition Width="Auto" />
                      <ColumnDefinition Width="*" />
                      <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                      <RowDefinition Height="Auto" />
                      <RowDefinition Height="*" />
                      <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Button Width="{Binding CellsPanelHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Command="{x:Static DataGrid.SelectAllCommand}" Focusable="false" Style="{DynamicResource {ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle,                                                                                           TypeInTargetAssembly={x:Type DataGrid}}}" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.All}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
                    <DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter" Grid.Row="0" Grid.Column="1" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Column}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
                    <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" CanContentScroll="{TemplateBinding CanContentScroll}" />
                    <ScrollBar x:Name="PART_VerticalScrollBar" Grid.Row="1" Grid.Column="2" Maximum="{TemplateBinding ScrollableHeight}" Orientation="Vertical" ViewportSize="{TemplateBinding ViewportHeight}" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" />
                    <Grid Grid.Row="2" Grid.Column="1">
                      <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
                        <ColumnDefinition Width="*" />
                      </Grid.ColumnDefinitions>
                      <ScrollBar x:Name="PART_HorizontalScrollBar" Grid.Column="1" Maximum="{TemplateBinding ScrollableWidth}" Orientation="Horizontal" ViewportSize="{TemplateBinding ViewportWidth}" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" />
                    </Grid>
                  </Grid>
                </ControlTemplate>
              </ScrollViewer.Template>
              <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
            </ScrollViewer>
            ...
          </Border>
        </ControlTemplate>
      </Setter.Value>
    </Setter>

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions