Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Two identical syncronized <ScrollViewer> components don't align #9817

Open
MIKAELMATZEN opened this issue Jul 14, 2024 · 6 comments
Open

Two identical syncronized <ScrollViewer> components don't align #9817

MIKAELMATZEN opened this issue Jul 14, 2024 · 6 comments
Labels
area-Scrolling bug Something isn't working team-Controls Issue for the Controls team

Comments

@MIKAELMATZEN
Copy link

MIKAELMATZEN commented Jul 14, 2024

Describe the bug

I have two ScrollViever components side by side, each containing a StackPanel with the same number of elements all of the same size. The two ScrollView components are synchronized through the ViewChanged event.

When one ScrollViewer is scrolled all the way to the bottom, the two ScrollViewer components are misaligned by one or two pixels. Scrolling the last pixel in the ScrollViewer I am scrolling does not trigger the ViewChanged event.

Steps to reproduce the bug

See the following XAML / C# code:

<Grid>

    <Grid.RowDefinitions>
        <RowDefinition Height="50"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="50"/>
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="50"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="50"/>
    </Grid.ColumnDefinitions>

    <ScrollViewer
        Grid.Row="1"
        Grid.Column="1"
        x:Name="LeftScrollViewer"
        ViewChanged="LeftScrollViewer_ViewChanged">

        <StackPanel
            Orientation="Vertical"
            Padding="0,0,0,0"
            Spacing="10">

            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>

        </StackPanel>
        
    </ScrollViewer>

    <ScrollViewer
        Grid.Row="1"
        Grid.Column="2"
        x:Name="RightScrollViewer"
        ViewChanged="RightScrollViewer_ViewChanged">

        <StackPanel
            Orientation="Vertical"
            Padding="0,0,0,0"                
            Spacing="10">

            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="Gray" HorizontalAlignment="Stretch"/>
            <Rectangle Height="50" Fill="DarkGray" HorizontalAlignment="Stretch"/>

        </StackPanel>

    </ScrollViewer>


</Grid>
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void LeftScrollViewer_ViewChanged( object sender, ScrollViewerViewChangedEventArgs e )
    {
        RightScrollViewer.ChangeView( null, LeftScrollViewer.VerticalOffset, null, true );
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void RightScrollViewer_ViewChanged( object sender, ScrollViewerViewChangedEventArgs e )
    {
        LeftScrollViewer.ChangeView( null, RightScrollViewer.VerticalOffset, null, true );
    }

Expected behavior

The two should move totally synchronized since the animation is disabled. When you try to scroll them all the wqy to the bottom you will see that one is misaligned by one or two pixels.

Screenshots

image

NuGet package version

WinUI 3 - Windows App SDK 1.6 Experimental 2: 1.6.240701003-experimental2

Windows version

No response

Additional context

My WIndows Version is 23H2

image

@MIKAELMATZEN MIKAELMATZEN added the bug Something isn't working label Jul 14, 2024
@microsoft-github-policy-service microsoft-github-policy-service bot added the needs-triage Issue needs to be triaged by the area owners label Jul 14, 2024
@kmgallahan
Copy link
Contributor

Does it repro with display scaling set to 100%?

@MIKAELMATZEN
Copy link
Author

@kmgallahan - no, it doesn't. At Display scaling 100% they align perfectly ...

@kmgallahan
Copy link
Contributor

That means layout rounding is used when the UI is scaled, and the positioning logic is different when handling input vs values set via code.

@MIKAELMATZEN
Copy link
Author

@kmgallahan - ok, thanks ...

Does that mean it is "works as designed", or that a fix will be created?

@codendone codendone added area-Scrolling team-Controls Issue for the Controls team and removed needs-triage Issue needs to be triaged by the area owners labels Jul 16, 2024
@kmgallahan
Copy link
Contributor

Most 'off by a pixel' stuff is related to scaling, so I just wanted to check if that was the case here.

Otherwise, I'm not an MS employee so no idea how they are allocating funding to resolve misc. aesthetic issues.

@MIKAELMATZEN
Copy link
Author

@kmgallahan - ok, thanks Kevin :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-Scrolling bug Something isn't working team-Controls Issue for the Controls team
Projects
None yet
Development

No branches or pull requests

3 participants