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.76k stars 704 forks source link

Support for `ItemsWrapGrid` #468

Open yowl opened 5 years ago

yowl commented 5 years ago

I'm submitting a...

Current behavior

ListView ItemsSource works in the playground, but seems to have a problem when the ItemsSource is changed after its rendered.

Expected behavior

ListView should redraw with all the items in its ItemsSource when the ItemsSource is changed (and notified)

Minimal reproduction of the problem with instructions

Clone https://github.com/yowl/UnoStandardRefTest/tree/wasmlistview and run the wasm head. Click the Load button and you should get 2 buttons as you do in the UWP head.

Environment

Nuget Package: Uno.UI

Package Version(s): 1.43.0-dev.564

Affected platform(s):
- [ ] iOS
- [ ] Android
- [ x] WebAssembly
- [ ] Windows
- [ ] Build tasks

Visual Studio
- [ ] 2017 (version: )
- [ ] 2017 Preview (version: )
- [ ] for Mac (version: )

Relevant plugins
- [ ] Resharper (version: )
yowl commented 5 years ago

Binding and x:Bind behave the same.

jeromelaban commented 5 years ago

This may have been fixed by #484, could you revalidate with latest master ?

yowl commented 5 years ago

image I'm still just getting the one item shown with Uno.UI 1.43.0-dev.614

yowl commented 5 years ago

As a simplification you can remove the binding and change the Xaml to

        <ListView x:Name="lst"
                  Grid.Column="1">
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <ItemsWrapGrid Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
        </ListView>

And in the button click

        private void Load(object sender, RoutedEventArgs e)
        {
            ViewModel.Reports = new List<ReportEntity>
                         {
                             new ReportEntity
                             {
                                 Key = 1, Name="a"
                             },
                             new ReportEntity
                             {
                             Key = 2, Name="b"
                         }
                         };
            lst.ItemsSource = ViewModel.Reports;
            Console.WriteLine("list items " + lst.Items.Count);
        }

One item will appear and Items.Count shows 0

yowl commented 5 years ago

and simpler:

        private void Load(object sender, RoutedEventArgs e)
        {
            lst.ItemsSource = new string [] {"a", "b"};
            Console.WriteLine("list items " + lst.Items.Count);
        }

is the same. I see https://github.com/nventive/Uno/blob/0a00b15b736983daa19474b8cb9fd667059ab2cd/src/Uno.UI/UI/Xaml/Controls/ItemsControl/ItemsControl.cs#L291 so can forget about Items.Count as that seems like a known difference

carldebilly commented 5 years ago

I just realized the problem is not related to the Items: if you check in the DOM, you can see your 2 items are there. They are "just" not arranged correctly.

I'll continue my investigations to fix this problem...

yowl commented 5 years ago

When I wrote this I thought it was the Items so sorry if I misled you there.

carldebilly commented 5 years ago

Source of the problem : ItemsWrapGrid is not implemented on Wasm. Only ItemsStackPanel is.

When a Panel is not implemented, only the first child gets measured & arranged, that's the default behavior of a FrameworkElement.

Possible workarounds:

yowl commented 5 years ago

WrapPanel with Orientation="Horizontal" is ok, Vertical is not a great workaround because the ListView just lets it expand and never wraps. I can make do with Horizontal for now.

DierkDroth commented 3 years ago
  • Use a WrapPanel instead, if you only have few items, it will work without the virtualization.

This suggests that WrapPanel would be supported whereas here it says it would not be supported.

@jeromelaban would you mind providing clarification? Thanks in advance

davidjohnoliver commented 3 years ago

@DierkDroth WrapPanel isn't listed on the page you link to because it's not a UWP control. It's an Uno-only panel that provides a layout similar to ItemsWrapGrid, but without virtualization.

DierkDroth commented 3 years ago

@davidjohnoliver now I'm even confused more:

What am I missing?

davidjohnoliver commented 3 years ago

@davidjohnoliver now I'm even confused more:

  • WrapPanel is listed on the page I linked above as "not supported"
  • WrapPanel appears to be a UWP control (pls see here)

What am I missing?

  1. My question is what am I missing 😄 I Ctrl-F'ed that page and couldn't find "WrapPanel" anywhere. Are you looking at WrapGrid by chance?
  2. That WrapPanel you're linking to is a Windows Community Toolkit control, not from UWP itself. No relation to the WrapPanel defined in Uno (as far as I know).
DierkDroth commented 3 years ago

On 1): My apologies. Crossed eyes on my end On 2): understand. Meaning the 'UNO version' of WrapPanel would work in the UNO UWP head as well?

davidjohnoliver commented 3 years ago

On 2): understand. Meaning the 'UNO version' of WrapPanel would work in the UNO UWP head as well?

No it won't, it's not part of the Uno.UI.Toolkit pieces that are available on the UWP head. It should be conditionally used for WASM only, per Carl's earlier comment.

DierkDroth commented 3 years ago

Thanks for clarification

jeromelaban commented 3 years ago

@DierkDroth there's a WrapPanel control available in the Windows Community Toolkit, if you need one available on all platforms.

DierkDroth commented 3 years ago

Thanks again @jeromelaban

SuperJMN commented 2 years ago

I thinks this https://github.com/unoplatform/uno/issues/4023 is related with this issue.