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

App freezes with ItemsPresenter + UniformGridLayout + Binding in ItemTemplate #6689

Closed
1 of 2 tasks
tristanlabelle opened this issue Feb 8, 2022 · 10 comments
Closed
1 of 2 tasks
Labels
area-Binding bug Something isn't working product-winui3 WinUI 3 issues team-Markup Issue for the Markup team

Comments

@tristanlabelle
Copy link

Describe the bug

Using a trivial combination of <ItemsPresenter>, <UniformGridLayout> and an ItemTemplate with a {Binding}, my app freezes. If I pause the execution in the debugger, WinUI seems to be stuck executing the UniformGridLayout measure phase:

 	KernelBase.dll!7624f649()	Unknown
 	KernelBase.dll![Frames below may be incorrect and/or missing, no symbols loaded for KernelBase.dll]	Unknown
 	Microsoft.UI.Xaml.Controls.dll!InspectingDataSource::GetAtCore(int)	Unknown
 	Microsoft.UI.Xaml.Controls.dll!winrt::impl::produce<ItemsSourceView,winrt::Microsoft::UI::Xaml::Controls::IItemsSourceView>::GetAt()	Unknown
 	Microsoft.UI.Xaml.Controls.dll!ViewManager::GetElementFromElementFactory()	Unknown
 	Microsoft.UI.Xaml.Controls.dll!ViewManager::GetElement()	Unknown
 	Microsoft.UI.Xaml.Controls.dll!RepeaterLayoutContext::GetOrCreateElementAtCore(int,enum winrt::Microsoft::UI::Xaml::Controls::ElementRealizationOptions const &)	Unknown
 	Microsoft.UI.Xaml.Controls.dll!winrt::impl::produce<VirtualizingLayoutContext,winrt::Microsoft::UI::Xaml::Controls::IVirtualizingLayoutContextOverrides>::GetOrCreateElementAtCore()	Unknown
 	Microsoft.UI.Xaml.Controls.dll!winrt::impl::consume_Microsoft_UI_Xaml_Controls_IVirtualizingLayoutContextOverrides<struct winrt::Microsoft::UI::Xaml::Controls::IVirtualizingLayoutContextOverrides>::GetOrCreateElementAtCore(int,enum winrt::Microsoft::UI::Xaml::Controls::ElementRealizationOptions const &)	Unknown
 	Microsoft.UI.Xaml.Controls.dll!winrt::impl::produce<VirtualizingLayoutContext,winrt::Microsoft::UI::Xaml::Controls::IVirtualizingLayoutContext>::GetOrCreateElementAt2()	Unknown
 	Microsoft.UI.Xaml.Controls.dll!winrt::impl::consume_Microsoft_UI_Xaml_Controls_IVirtualizingLayoutContext<struct winrt::Microsoft::UI::Xaml::Controls::IVirtualizingLayoutContext>::GetOrCreateElementAt(int,enum winrt::Microsoft::UI::Xaml::Controls::ElementRealizationOptions const &)	Unknown
 	Microsoft.UI.Xaml.Controls.dll!UniformGridLayoutState::EnsureElementSize(struct winrt::Windows::Foundation::Size,struct winrt::Microsoft::UI::Xaml::Controls::VirtualizingLayoutContext const &,double,double,enum winrt::Microsoft::UI::Xaml::Controls::UniformGridLayoutItemsStretch const &,enum winrt::Microsoft::UI::Xaml::Controls::Orientation const &,double,double,unsigned int)	Unknown
 	Microsoft.UI.Xaml.Controls.dll!UniformGridLayout::MeasureOverride(struct winrt::Microsoft::UI::Xaml::Controls::VirtualizingLayoutContext const &,struct winrt::Windows::Foundation::Size const &)	Unknown
 	Microsoft.UI.Xaml.Controls.dll!winrt::impl::produce<VirtualizingLayout,winrt::Microsoft::UI::Xaml::Controls::IVirtualizingLayoutOverrides>::MeasureOverride()	Unknown
 	Microsoft.UI.Xaml.Controls.dll!Layout::Measure()	Unknown

Steps to reproduce the bug

  1. Create a new Blank App, Packaged (WinUI 3 in Desktop) app.
  2. Add this xaml to MainWindow.xaml:
    <ItemsRepeater ItemsSource="{Binding Items}">
        <ItemsRepeater.Layout>
            <UniformGridLayout />
        </ItemsRepeater.Layout>
        <ItemsRepeater.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Text}" />
            </DataTemplate>
        </ItemsRepeater.ItemTemplate>
    </ItemsRepeater>
  1. Add this to the codebehind
        public MainWindow()
        {
            this.InitializeComponent();
            ((FrameworkElement)this.Content).DataContext = this;
        }

        public Item[] Items { get; } = new[]
        {
            new Item() { Text = "foo" },
            new Item() { Text = "bar" },
        };

        public sealed class Item
        {
            public string Text { get; set; }
        }
  1. Run the app

Expected behavior

The app shows "foo bar" and is responsive.

Screenshots

No response

NuGet package version

WinUI 3 - Windows App SDK 1.0 (If you're seeing your issue in older previews of WinUI 3, please try this release)

Windows app type

  • UWP
  • Win32

Device form factor

Desktop

Windows version

No response

Additional context

Windows 11, v21H2, 22000.434

@ghost ghost added the needs-triage Issue needs to be triaged by the area owners label Feb 8, 2022
@kmgallahan
Copy link
Contributor

kmgallahan commented Feb 8, 2022

This works fine:

    <ItemsRepeater ItemsSource="{x:Bind Items}">
        <ItemsRepeater.Layout>
            <UniformGridLayout />
        </ItemsRepeater.Layout>
        <ItemsRepeater.ItemTemplate>
            <DataTemplate x:DataType="local:Item">
                <TextBlock Text="{x:Bind Text}" />
            </DataTemplate>
        </ItemsRepeater.ItemTemplate>
    </ItemsRepeater>
    public sealed class Item
    {
        public string Text { get; set; }
    }

    public sealed partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.InitializeComponent();
        }

        public Item[] Items { get; } = new[]
        {
            new Item() { Text = "foo" },
            new Item() { Text = "bar" },
        };
    }

Screenshot 2022-02-08 114923

@tristanlabelle
Copy link
Author

@kmgallahan, are you saying that the bug is no repro or that x:Bind is a workaround?

@kmgallahan
Copy link
Contributor

I can repro the original issue.

My first thought when seeing problems with Binding is if x:bind will work instead since it is newer / recommended. It works so I felt it would be worth mentioning in case this was blocking you.

@StephenLPeters StephenLPeters added area-Binding product-winui3 WinUI 3 issues team-Markup Issue for the Markup team labels Mar 4, 2022
@StephenLPeters
Copy link
Contributor

Thanks kmgallahan! @fabiant3 FYI on the Binding issue.

@bpulliam bpulliam removed the needs-triage Issue needs to be triaged by the area owners label Dec 6, 2022
@arnaud-netinfluence
Copy link

I've run into a similar bug while using ItemsRepeater.ItemTemplate attribute :

This code freezes:

<ItemsRepeater ItemsSource="{Binding Items}" ItemTemplate={StaticResource MyTemplate}>
    <ItemsRepeater.Layout>
        <UniformGridLayout />
    </ItemsRepeater.Layout>
</ItemsRepeater>

I found this workaround :

<ItemsRepeater ItemsSource="{Binding Items}">
    <ItemsRepeater.Layout>
        <UniformGridLayout />
    </ItemsRepeater.Layout>
    <ItemsRepeater.ItemTemplate >
        <DataTemplate >
            <ContentControl ContentTemplate="{StaticResource MyTemplate}"></ContentControl>
       </DataTemplate>
    </ItemsRepeater.ItemTemplate>
</ItemsRepeater>

@Pospeno
Copy link

Pospeno commented Dec 19, 2022

I can reproduce the issue, swapped x:bind to binding and it wouldn't help...
It seems to be ok with simple item templates... like a single image with a bind on its source, but things breaks down when multiple bindings are involved, if I had to guess it has something do with the recycling and virtualizing part of the layout.

Its crazy that this still persists after a year, how very disappointing.

@agneszitte
Copy link
Contributor

agneszitte commented Jan 19, 2023

I've run into a similar bug

I've also run into a similar bug on my side while using muxc:ItemsRepeater + muxc:UniformGridLayout + Binding in ItemTemplate.
I didn't find a workaround for it yet, I've even tried the workaround @arnaud-netinfluence shared here but it's not working in my case sadly.
Another related issue: #6799

(cc @StephenLPeters, @bpulliam, @fabiant3, @michael-hawker)

@dr1rrb
Copy link

dr1rrb commented Jan 20, 2023

We investigated the issue with @agneszitte-nventive and we found that indeed there is a layout cycling issue related to bindings: IR is measuring again and again the same item, but measured size returned by the item changes (Depending if binding are applied or not yet? Appears also that bindings can be reset ... does item is detached from visual tree / data-context cleared by IR while it measures the first item?)

Removing bindings in the template OR fixing the size of the root element does "fix" the issue ... but it's not responsive and defeats the main purpose of the UniformGridLayout.

A better work-around is then to "stabilize" the size of the root element, especially on the "non scrolling / wrapping axis" (i.e. horizontally in common usage). For this we altered the measure of the root element (created a Control that inherits from the desired control) to "stretch" along the wrapping axis:

protected override Size MeasureOverride(Size availableSize)
    => new Size(availableSize.Width, base.MeasureOverride(availableSize).Height);

We also made sure to remove all sizing constraints on that element (for instance, we removed MaxWidth) as those constraints are impacting the availableSize and will therefore prevent proper stretching and alignment of the item. We also made sure to "help" the ItemsRepeater to determine the size of its items by providing explicit values to the MinItemWidth and MaximumRowsOrColumns on the UniformWrapGrid.

@agneszitte
Copy link
Contributor

I can confirm that using x:Bind instead is working properly as a workaround in some cases

@RBrid
Copy link
Contributor

RBrid commented Jun 4, 2024

I have not been able to reproduce this with the WinAppSDK version 1.5.240428000, so closing this issue for now.

@RBrid RBrid closed this as completed Jun 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-Binding bug Something isn't working product-winui3 WinUI 3 issues team-Markup Issue for the Markup team
Projects
None yet
Development

No branches or pull requests

10 participants