unoplatform / uno

Build Mobile, Desktop and WebAssembly apps with C# and XAML. Today. Open source and professionally supported.
https://platform.uno
Apache License 2.0
8.6k stars 693 forks source link

ItemsRepeater flicker when we data-bind the visibility of the items #16771

Open dr1rrb opened 1 month ago

dr1rrb commented 1 month ago

Current behavior

When we have a view like this:

<ItemsRepeater ItemsSource="{Binding MySource}">
    <ItemsRepeater.ItemTemplate>
        <DataTemplate>
            <Border>
                <TextBlock Text="{Binding Value}" Visiblity="{Binding IsVisible}" />
            </Border>
        </DataTemplate>
    </ItemsRepeater.ItemTemplate>
</ItemsRepeater>

Note the binding on Visiblity="{Binding IsVisible}" on the TextBlock.

This cause some flicker when scrolling, especially if there are nested ItemsRepeater doing the same!

Expected behavior

No flicker and proper alignment of items!

How to reproduce it (as minimally and precisely as possible)

Workaround

DO NOT Data-bind the visibility of items, instead remove and add them back to the MySource collection.


IMPORTANT

The "workaround" is actually the recommended way to do as it is (significantly) more performant as:

  1. It avoids materialization of items that are finally hidden
  2. Data-binding the visibility might (always?) cause an additional layouting pass!

Works on UWP/WinUI

None

NuGet package version(s)

5.2

Affected platforms

Uno ... but the issue might be the same on windows and should be tested first!

Youssef1313 commented 1 month ago

@dr1rrb Is this about ItemsRepeaterManyItems sample? Are you testing Gtk or WPF?

For Gtk, it's a known problem which I tried to fix, but the fix broke Gallery canary so it was reverted. See https://github.com/unoplatform/uno/pull/15811

Youssef1313 commented 1 month ago

I can try another fix though

dr1rrb commented 1 month ago

@dr1rrb Is this about ItemsRepeaterManyItems sample? Are you testing Gtk or WPF?

For Gtk, it's a known problem which I tried to fix, but the fix broke Gallery canary so it was reverted. See #15811

Eh eh no it was only to have an issue to track my time ... but since I now found the root cause I can rename it and add details :)

ramezgerges commented 4 weeks ago

This needs a more detailed information. I tried this but no flickering happened:

// in sample constructor:
ir.DataContext = Enumerable.Range(0, 1000).Select(i => new VM(i.ToString(), i % 2 == 0)).ToList();

public class VM
{
    private string value;
    private bool isVisible;

    public VM(string value, bool isVisible)
    {
        this.value = value;
        this.isVisible = isVisible;
    }
    public string Value => value;
    public bool IsVisible => isVisible;
}
<ScrollViewer Height="400">
      <ItemsRepeater x:Name="ir" ItemsSource="{Binding}">
        <ItemsRepeater.ItemTemplate>
          <DataTemplate>
            <Border Visibility="{Binding IsVisible}">
              <TextBlock Text="{Binding Value}" />
            </Border>
          </DataTemplate>
        </ItemsRepeater.ItemTemplate>
      </ItemsRepeater>
    </ScrollViewer>

However, there is some extreme corruption happening. Reported in https://github.com/unoplatform/uno/issues/16992

dr1rrb commented 3 weeks ago

However, there is some extreme corruption happening. Reported in #16992

That's what I call "flicker" since it's when you scroll (depending of the scroll direction you will be able to see some items or not). Closing https://github.com/unoplatform/uno/issues/16992 as duplicate of this.

Edit: Feel free to rename this issue if you find it not descriptive enough ;)