Microsoft-ui-xaml: Huge gap in RadioButtons when last item is a long string

Created on 13 Jul 2020  ·  8Comments  ·  Source: microsoft/microsoft-ui-xaml

Describe the bug
When using RadioButtons, having a very long item as the last item will make the RadioButtons list have an unnecessary huge margin among them.

Steps to reproduce the bug
Create a RadioButtons group and set the last element with a long-ish string. The RadioButtons will get created with unnecessary huge margins.

Expected behavior
It should look like the first list from here screenshot 1.

Screenshots
Screenshot 1
image

Version Info
WinUI 2.4

NuGet package version:
Microsoft.UI.Xaml 2.4.0


| Windows 10 version | Saw the problem? |
| :--------------------------------- | :-------------------- |
| Insider Build (xxxxx) | |
| May 2020 Update (19041) | Yes |
| November 2019 Update (18363) | |
| May 2019 Update (18362) | |
| October 2018 Update (17763) | |
| April 2018 Update (17134) | |
| Fall Creators Update (16299) | |
| Creators Update (15063) | |


| Device form factor | Saw the problem? |
| :----------------- | :--------------- |
| Desktop | Yes |
| Xbox | |
| Surface Hub | |
| IoT | |

area-RadioButtons duplicate team-Controls

Most helpful comment

Currently the only "real" solution is to switch the layout to a different one that behaves differently with large number of strings.
Unfortunately, the only way you can do this right now is through retemplating. The following RadioButtons template should work better, but also renders the radiobuttons only in a list with 1 column:

<!-- Retemplate inside control -->
<muxc:RadioButtons MaxColumns="1" Header="Border" SelectedIndex="2" >
    <muxc:RadioButtons.Template>
        <ControlTemplate TargetType="muxc:RadioButtons">
            <StackPanel>
                <ContentPresenter
            Content="{TemplateBinding Header}"
            ContentTemplate="{TemplateBinding HeaderTemplate}"/>
                <muxc:ItemsRepeater x:Name="InnerRepeater" ItemTemplate="{TemplateBinding ItemTemplate}">
                    <muxc:ItemsRepeater.Layout>
                        <muxc:StackLayout />
                    </muxc:ItemsRepeater.Layout>
                </muxc:ItemsRepeater>
            </StackPanel>
        </ControlTemplate>
    </muxc:RadioButtons.Template>
    <x:String>Green</x:String>
    <x:String>Yellow</x:String>
    <x:String>White</x:String>
    <x:String>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc sagittis nisi consequat mauris volutpat, eget lacinia orci fermentum. Phasellus id justo ac lorem mattis facilisis ac sit amet diam. Proin porttitor et est at dignissim. Nulla pulvinar, eros eu commodo elementum, mi nisl ultrices ante, ut imperdiet elit leo ut nunc. Morbi quis imperdiet arcu. Curabitur eget ex nec tellus pharetra facilisis eget et velit. Fusce semper velit ut mauris suscipit viverra. Nulla at nulla at libero tempor eleifend vel ac ex.</x:String>
</muxc:RadioButtons>

<!-- Retemplate style -->
<Style TargetType="muxc:RadioButtons" x:Key="StackLayoutRadioButtons">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="muxc:RadioButtons">
                <StackPanel>
                    <ContentPresenter
                    Content="{TemplateBinding Header}"
                    ContentTemplate="{TemplateBinding HeaderTemplate}"/>
                    <muxc:ItemsRepeater x:Name="InnerRepeater" ItemTemplate="{TemplateBinding ItemTemplate}">
                        <muxc:ItemsRepeater.Layout>
                            <muxc:StackLayout />
                        </muxc:ItemsRepeater.Layout>
                    </muxc:ItemsRepeater>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Giving you the following result:
image


This issue is another example of a use case for #2084 . Is there anything stopping #2084 right now, or would it be fine if I start to work on this @ranjeshj?

All 8 comments

<muxc:RadioButtons MaxColumns="1" Header="Background" SelectedIndex="1" SelectionChanged="BackgroundColor_SelectionChanged">
                    <x:String>Green</x:String>
                    <x:String>Yellow</x:String>
                    <x:String>White</x:String>
                    <x:String>Lorem</x:String>
                </muxc:RadioButtons>
                <muxc:RadioButtons MaxColumns="1" Header="Border" SelectedIndex="2" SelectionChanged="BorderBrush_SelectionChanged">
                    <x:String>Green</x:String>
                    <x:String>Yellow</x:String>
                    <x:String>White</x:String>
                    <x:String>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc sagittis nisi consequat mauris volutpat, eget lacinia orci fermentum. Phasellus id justo ac lorem mattis facilisis ac sit amet diam. Proin porttitor et est at dignissim. Nulla pulvinar, eros eu commodo elementum, mi nisl ultrices ante, ut imperdiet elit leo ut nunc. Morbi quis imperdiet arcu. Curabitur eget ex nec tellus pharetra facilisis eget et velit. Fusce semper velit ut mauris suscipit viverra. Nulla at nulla at libero tempor eleifend vel ac ex.</x:String>
</muxc:RadioButtons>

I think the issue here is the layout the RadioButtons use which is a ColumnMajorUniformToLargestGridLayout, which sizes every item based on the largest in the column.

Is there any viable workaround? Setting negative margins/padding doesn't fix it completely (and doesn't look good either).

Currently the only "real" solution is to switch the layout to a different one that behaves differently with large number of strings.
Unfortunately, the only way you can do this right now is through retemplating. The following RadioButtons template should work better, but also renders the radiobuttons only in a list with 1 column:

<!-- Retemplate inside control -->
<muxc:RadioButtons MaxColumns="1" Header="Border" SelectedIndex="2" >
    <muxc:RadioButtons.Template>
        <ControlTemplate TargetType="muxc:RadioButtons">
            <StackPanel>
                <ContentPresenter
            Content="{TemplateBinding Header}"
            ContentTemplate="{TemplateBinding HeaderTemplate}"/>
                <muxc:ItemsRepeater x:Name="InnerRepeater" ItemTemplate="{TemplateBinding ItemTemplate}">
                    <muxc:ItemsRepeater.Layout>
                        <muxc:StackLayout />
                    </muxc:ItemsRepeater.Layout>
                </muxc:ItemsRepeater>
            </StackPanel>
        </ControlTemplate>
    </muxc:RadioButtons.Template>
    <x:String>Green</x:String>
    <x:String>Yellow</x:String>
    <x:String>White</x:String>
    <x:String>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc sagittis nisi consequat mauris volutpat, eget lacinia orci fermentum. Phasellus id justo ac lorem mattis facilisis ac sit amet diam. Proin porttitor et est at dignissim. Nulla pulvinar, eros eu commodo elementum, mi nisl ultrices ante, ut imperdiet elit leo ut nunc. Morbi quis imperdiet arcu. Curabitur eget ex nec tellus pharetra facilisis eget et velit. Fusce semper velit ut mauris suscipit viverra. Nulla at nulla at libero tempor eleifend vel ac ex.</x:String>
</muxc:RadioButtons>

<!-- Retemplate style -->
<Style TargetType="muxc:RadioButtons" x:Key="StackLayoutRadioButtons">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="muxc:RadioButtons">
                <StackPanel>
                    <ContentPresenter
                    Content="{TemplateBinding Header}"
                    ContentTemplate="{TemplateBinding HeaderTemplate}"/>
                    <muxc:ItemsRepeater x:Name="InnerRepeater" ItemTemplate="{TemplateBinding ItemTemplate}">
                        <muxc:ItemsRepeater.Layout>
                            <muxc:StackLayout />
                        </muxc:ItemsRepeater.Layout>
                    </muxc:ItemsRepeater>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Giving you the following result:
image


This issue is another example of a use case for #2084 . Is there anything stopping #2084 right now, or would it be fine if I start to work on this @ranjeshj?

@kikisaints and @StephenLPeters as FYI. Exposing the layout as a property seems like the correct thing to do, but I think there were some concerns with keyboarding.

@StephenLPeters' last comment sounded more like, that we would figure this out while we are implementing this. But maybe we need to figure this out beforehand? We can not provide optimal keyboarding for any layout since this would require knowledge of the layout being passed, so maybe we should expose a property/type/interface that can provide functions for moving focus? @MikeHillberg FYI

Edit: Maybe we should continue that discussion in #2084

The issue with allowing custom layouts is the keyboarding we have right now is tied to the layout so we would need a way to disable/allow custom keyboarding behavior as well.

Duplicate of #2084

Was this page helpful?
0 / 5 - 0 ratings