unoplatform / uno.toolkit.ui

A set of custom controls for the WinUI and the Uno Platform not offered out of the box by WinUI, such as Card, TabBar, NavigationBar, etc.
https://platform.uno/
MIT License
83 stars 27 forks source link

Grid cells do not fill the page #1259

Open MartinZikmund opened 2 months ago

MartinZikmund commented 2 months ago

I have been a WPF developer since 2006 and have written thousands of lines of WPF xaml code without issue. Maui, because Mirocosoft has to have a billion different versions of xaml, made me learn YAXL (yet another Xaml language), but I figured it out. Then, here comes Uno which uses WinUI 3... I am probably needing to quit my day job and go be a greeter at Walmart because I just cannot figure this out.

I am doing a poor-man's version of navitation. I have a list view with cells, that when selected, set the content of a content control on the main page to the page that was selected.

This is the definition of the main page:

<Page
    x:Class="MobyClient.Presentation.Views.MainPage"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:ut="using:Uno.Themes"
    xmlns:utu="using:Uno.Toolkit.UI"
    xmlns:utum="using:Uno.Toolkit.UI.Material"
    xmlns:viewModels="using:MobyClient.Presentation.ViewModels"
    xmlns:views="using:MobyClient.Presentation.Views"
    xmlns:converters="using:MobyClient.Converters">
    <Page.Resources>
        <converters:BoolToVisibilityConverter
            x:Key="BoolToVisibilityConverter" />
    </Page.Resources>
    <Grid
        utu:SafeArea.Insets="All"
        HorizontalAlignment="Stretch"
        VerticalAlignment="Stretch">
        <Grid.RowDefinitions>
            <RowDefinition
                Height="54" />
            <RowDefinition
                Height="*" />
        </Grid.RowDefinitions>
        <!-- Top Navbar -->
        <!-- Removed for brevity -->
        <!-- Main Panel -->
        <Grid
            Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition
                    Width="130" />
                <ColumnDefinition
                    Width="*" />
            </Grid.ColumnDefinitions>
            <!-- Page Selector -->
            <ListView
                x:FieldModifier="Public"
                x:Name="SelectablePages"
                Grid.Column="0"
                Background="{StaticResource MobyDarkToolBarBackground}"
                CornerRadius="0"
                ItemContainerStyle="{StaticResource MainListViewItemStyle}"
                ItemsSource="{Binding Pages}"
                ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                ScrollViewer.VerticalScrollBarVisibility="Auto"
                Width="130" />
            <!-- Content Panel -->
            <ContentControl
                x:Name="PageControl"
                Grid.Column="1"
                VerticalAlignment="Stretch"
                HorizontalAlignment="Stretch" />
        </Grid>
    </Grid>
</Page>

I have a SelectionChanged event handler in the Main.xaml.cs code-behind that handles the page set up. It works fine as the pages change as I need them to. But... for the life of me, I cannot get any page that is loaded as the content of the content control to consume the entire page surface. I have tried using AutoLayout, but that didn't work as I could get two out of three columns to fill properly, but I could never get all three columns to fill. When I added a listview to the third column, suddenly all of the column's vertical height get set to the tallest column but it was still shorter than the panel height. I tried changing the type of the content being loaded into the content control to UserControl, but that didn't fix it.

This is the abbreviated code of a page I am trying to load:

<Page
    x:Class="MobyClient.Presentation.Views.ChatMessagesPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Name="ChatMessages">
    <Page.Resources>
        <!--<converters:BoolToVisibilityConverter
            x:Key="BoolToVisibilityConverter" />
        <converters:ImagePathToImageSourceConverter
            x:Key="ImagePathToImageSourceConverter" />
        --><!-- Define the context action button item template --><!--
        <DataTemplate
            x:Key="ContextActionsItemTemplate">
            <Image
                Height="24"
                Margin="-22,10,0,10"
                Source="{Binding IconName}"
                Stretch="Uniform"
                VerticalAlignment="Center"
                Width="24" />
        </DataTemplate>
        --><!-- Define the context action button separator template --><!--
        <DataTemplate
            x:Key="ContextActionsSeparatorTemplate">
            <Path
                Data="M 38 0 C 34.34074087496157 0 11.141975084940592 0 0 0"
                HorizontalAlignment="Center"
                Margin="-22,20,0,20"
                Stroke="White"
                StrokeThickness="2"
                Width="38" />
        </DataTemplate>-->
    </Page.Resources>
    <Grid
        HorizontalAlignment="Stretch"
        VerticalAlignment="Stretch">
        <Grid.ColumnDefinitions>
            <ColumnDefinition
                Width="64" />
            <ColumnDefinition />
            <ColumnDefinition
                Width="Auto" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition
                Height="*" />
        </Grid.RowDefinitions>
        <Border
            Grid.Column="0"
            Grid.Row="1"
            Background="Green"
            VerticalAlignment="Stretch">
            <Grid>
                <TextBlock
                    Grid.Column="0"
                    Text="This is the chat messages page!"
                    VerticalAlignment="Center" />
            </Grid>
        </Border>
        <Border
            Grid.Column="1"
            Background="Purple"
            VerticalAlignment="Stretch">
            <TextBlock
                Grid.Column="1"
                Text="This is the chat messages page!"
                VerticalAlignment="Center" />
        </Border>
        <Border
            Grid.Column="2"
            Background="Blue"
            VerticalAlignment="Stretch">
            <TextBlock
                Grid.Column="2"
                Text="This is the chat messages page!"
                VerticalAlignment="Center" />
        </Border>
    </Grid>
</Page>

It just ends up looking like this:

image

If I change the MainPage to this:

<Page
    x:Class="MobyClient.Presentation.Views.MainPage"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:ut="using:Uno.Themes"
    xmlns:utu="using:Uno.Toolkit.UI"
    xmlns:utum="using:Uno.Toolkit.UI.Material"
    xmlns:viewModels="using:MobyClient.Presentation.ViewModels"
    xmlns:views="using:MobyClient.Presentation.Views"
    xmlns:converters="using:MobyClient.Converters">
    <Page.Resources>
        <converters:BoolToVisibilityConverter
            x:Key="BoolToVisibilityConverter" />
    </Page.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition
                Width="3*" />
            <ColumnDefinition
                Width="5*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition
                Height="2*" />
            <RowDefinition
                Height="*" />
        </Grid.RowDefinitions>
        <Border
            Background="#2f5cb6" />
        <Border
            Grid.Column="1"
            Background="#1f3d7a" />
        <Border
            Grid.Row="1"
            Grid.ColumnSpan="2"
            Background="#152951" />
    </Grid>
</Page>

I get this, which is what I want:

image

What is it about a page that is being loaded into a content control on the main page does not render the same way it renders the main page does when that is all the xaml tells it to do???

I know this is something extremely simple, but I have spent hours and tried a million things to make this work. My bet is that if one of you smart guys that reads this you will see the error immediately. I just can't look at it any longer!!!

Originally posted by @mobynet1 in https://github.com/unoplatform/uno/discussions/18221

jeromelaban commented 2 months ago

@mobynet1 could you tell if this issue happens on the net8.0-windows head?

mobynet1 commented 2 months ago

@jeromelaban This happens on WinAppSDK Unpackaged as well as Desktop.

I think I've put my finger on the issue and it points to the AutoLayout.

This works:

<Page
  x:Class="UnoApp1.Presentation.MainPage"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="using:UnoApp1.Presentation"
  xmlns:uen="using:Uno.Extensions.Navigation.UI"
  xmlns:utu="using:Uno.Toolkit.UI"
  xmlns:um="using:Uno.Material"
  NavigationCacheMode="Required"
  Background="{ThemeResource BackgroundBrush}">
  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition
        Width="3*" />
      <ColumnDefinition
        Width="5*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition
        Height="2*" />
      <RowDefinition
        Height="*" />
    </Grid.RowDefinitions>
    <Border
      Background="#2f5cb6" />
    <Border
      Grid.Column="1"
      Background="#1f3d7a" />
    <Border
      Grid.Row="1"
      Grid.ColumnSpan="2"
      Background="#152951" />
  </Grid>
</Page>

which produces:

image

And this does not work:

<Page
  x:Class="UnoApp1.Presentation.MainPage"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="using:UnoApp1.Presentation"
  xmlns:uen="using:Uno.Extensions.Navigation.UI"
  xmlns:utu="using:Uno.Toolkit.UI"
  xmlns:um="using:Uno.Material"
  NavigationCacheMode="Required"
  Background="{ThemeResource BackgroundBrush}">
  <utu:AutoLayout>
    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition
          Width="3*" />
        <ColumnDefinition
          Width="5*" />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition
          Height="2*" />
        <RowDefinition
          Height="*" />
      </Grid.RowDefinitions>
      <Border
        Background="#2f5cb6" />
      <Border
        Grid.Column="1"
        Background="#1f3d7a" />
      <Border
        Grid.Row="1"
        Grid.ColumnSpan="2"
        Background="#152951" />
    </Grid>
  </utu:AutoLayout>
</Page>

Which produces this:

image

The only difference between the two is the latter is wrapped inside the AutoLayout control. Is it in the way that I am using the AutoLayout control? Here, I am not using any properties to the control, but believe me, I have tried almost every property in almost every combination and it just misbehaves...

MartinZikmund commented 2 months ago

Cc @kazo0

kazo0 commented 1 month ago

Setting the Primary/Counter Alignments on the Grid through the AutoLayout AttachedProperties should do the trick:

<utu:AutoLayout>
    <Grid utu:AutoLayout.PrimaryAlignment="Stretch" utu:AutoLayout.CounterAlignment="Stretch">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="3*" />
            <ColumnDefinition Width="5*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="2*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Border Background="#2f5cb6" />
        <Border Grid.Column="1"
                Background="#1f3d7a" />
        <Border Grid.Row="1"
                Grid.ColumnSpan="2"
                Background="#152951" />
    </Grid>
</utu:AutoLayout>
image

Although, I would have thought that setting the PrimaryAxisAlignment and CounterAxisAlignment directly on the root AutoLayout would work as well. It doesn't seem to work properly in that case.

I have transferred this issue to the Toolkit repo so we can investigate