Microsoft-ui-xaml: ItemsRepeater renders only the first item when no ScrollViewer in the visual tree under a popup

Created on 28 Apr 2020  路  5Comments  路  Source: microsoft/microsoft-ui-xaml

Describe the bug
If there is no ScrollViewer in the parent visual tree of an ItemsRepeater, then it will render only the first item.

Steps to reproduce the bug

  1. Create a blank app, in the MainPage put:

_MainPage.xaml_

<Grid>
    <Popup x:Name="popup" IsOpen="True">
        <controls:ItemsRepeater x:Name="SUT" />
    </Popup>
</Grid>

_MainPage.xaml.cs_

SUT.ItemsSource = Enumerable.Range(0, 10);

Expected behavior
As the Popup is tall enough, we should see all 10 items.

Screenshots
image

Version Info

  • Microsoft.UI.Xaml: _2.4.0-prerelease.200322001_
  • Windows: 1909 18363.778_
  • Project's target and min version: _18362_
  • Device: _Desktop_

Additional context
According to my tests, this is because in the ViewportManagerWithPlatformFeatures, if we cannot find any scroller we init the viewport with an empty rect.
This drives the GetLayoutRealizationWindow to return an empty Rect.
This "window" is used by the FlowLayoutAlgorithm.ShouldContinueFillingUpSpace(), which concludes that the viewport/window is full and stops the elements generation after the first one.

Note: this is not visible out of a Popup as a normal Window does have a ScrollViewer in its "template".

area-ItemsRepeater needs-winui-3 team-Controls

Most helpful comment

Hi @ranjeshj , yes it works:

<Grid>
    <Popup x:Name="popup" IsOpen="True">
        <ScrollViewer>
            <controls:ItemsRepeater x:Name="SUT" />
        </ScrollViewer>
    </Popup>
</Grid>

image

But it's a valid use case to not use one. I would have fix it by myself, just I'm not a huge fan of C++ :)

All 5 comments

@dr1rrb That is correct. ItemsRepeater uses the EffectiveViewport event which provides it the viewport (could be coming from scrollviewers in the tree above). Looks like there are cases where this event is not getting raised which leaves the rect to be empty. Stack/UniformGrid layouts use the realization rect to figure out how many items to realize. They realize the first element to figure out relatively how big the extent is going to be, but if the rect is empty, they don't go any further.

Does it work if you add a ScrollViewer into the tree under the popup ?

Hi @ranjeshj , yes it works:

<Grid>
    <Popup x:Name="popup" IsOpen="True">
        <ScrollViewer>
            <controls:ItemsRepeater x:Name="SUT" />
        </ScrollViewer>
    </Popup>
</Grid>

image

But it's a valid use case to not use one. I would have fix it by myself, just I'm not a huge fan of C++ :)

Thanks for confirming. I agree that the ScrollViewer should not be required. I think this is similar to #2102 and needs fix in the framework (will need to be post WinUI3).

The issue is that if there is no scroller we don't even subscribe to the EffectiveViewportChanged event. So except if you plan that a root control (like the Popup in that case) implements IScrollAnchorProvider, I think that fixing #2102 would not fix this case.

Was this page helpful?
0 / 5 - 0 ratings