dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
22k stars 1.72k forks source link

[Bug] Grid Row Configuration of Auto, * produces 0 height for second row. #1999

Closed drasticactions closed 3 years ago

drasticactions commented 3 years ago

Description

Given a Grid with a row configuration of "Auto, *", the second row seems to not be able to render any content. The only way to get the content to render is to either set a height to Auto, or set the content height for the second row.

This doesn't happen in Forms, for example.

https://user-images.githubusercontent.com/898335/128616208-3340419d-ab5d-4ff3-a780-db6f63324f8a.mp4

Where in Maui, it's like this.

https://user-images.githubusercontent.com/898335/128616223-208126fa-f8c9-435d-84c8-46a4348eb194.mp4

Steps to Reproduce

Use the provided Maui and Xamarin.Forms Sample Apps

FormsApp.zip MauiTestApp.zip

hartez commented 3 years ago

tl;dr; change your markup to this:

<Grid x:Name="StatusGrid" Margin="0" Grid.Column="1" RowSpacing="6">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid Grid.Row="0" >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
    <Label Grid.Column="0" Padding="5,0,0,0" Text="{Binding Field1}" 
               MaxLines="1" LineBreakMode="TailTruncation" FontAttributes="Bold" />
    </Grid>
    <Grid Margin="5,0,0,0" Grid.Row="1">
        <Label Text="{Binding Field2}"/>
    </Grid>
</Grid>

The changes are the RowSpacing (the defaults changed from Forms to MAUI) and the "Auto" row definition in the first inner Grid.

hartez commented 3 years ago

Now for the long version:

I'm pretty sure this is a bug in Forms. The markup doesn't make sense for the output.

The relevant section is

<Grid x:Name="StatusGrid" Margin="0" Grid.Column="1">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid Grid.Row="0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Label Grid.Column="0" Padding="5,0,0,0" Text="{Binding Field1}" MaxLines="1" LineBreakMode="TailTruncation" FontAttributes="Bold" />
    </Grid>
    <Grid Margin="5,0,0,0" Grid.Row="1">
        <Label Text="{Binding Field2}"/>
    </Grid>
</Grid>

The outer Grid has two rows, "Auto" and "*". The auto row should choose a value that fits the children inside it, and the "" should get 100% of the remaining space. The Grid inside the auto row has an implied RowDefinition of "\" (the default) - which means it should get 100% of the available space available to it. At this point, that should mean "all the vertical space", since nothing else is constraining it.

For some reason, the Forms version is behaving as if the inner Grid has a RowDefinition of "Auto", rather than "*". In fact, if you explicitly set the RowDefinitions for that inner Grid and select "Auto" or "*", you'll get the exact same behavior for both. So I'm pretty sure this is a bug.

The behavior you're looking for (i.e., where the first inner Grid is only the size of the Field1 Label) can be achieved in MAUI by setting the inner Grid's RowDefinition to "Auto" (see the XAML in the previous comment).

hartez commented 3 years ago

Also, I'm not sure what all the extra Grids are for (testing purposes?), so this may not be helpful, but the "StatusGrid" markup can be simplified for much better performance. This should achieve the same effect:

<StackLayout x:Name="StatusGrid" Spacing="5">
    <Label HorizontalOptions="Start" Padding="5,0,0,0" Text="{Binding Field1}" 
            MaxLines="1" LineBreakMode="TailTruncation" FontAttributes="Bold" />
    <Label Margin="5,0,0,0" Text="{Binding Field2}"/>
</StackLayout>
drasticactions commented 3 years ago

@hartez Originally StatusGrid had an additional row that had attached media images that would load if they were attached to a post. I removed it while I was refactoring for Maui and I agree that the XAML itself could be simplified. I just saw that it wasn't matching what was originally written in Forms.

I'll close this, changing it to what it should be isn't a "workaround" so I'm fine with it. IMO we should probably promote "RowSpacing" more since I didn't know that existed until you mentioned it and it's very useful!