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
21.83k stars 1.67k forks source link

MAUI: Compatibility.Layout<T> doesn't display anything without child.Measure #22884

Open JTOne123 opened 1 month ago

JTOne123 commented 1 month ago

Description

I struggle with Xamarin -> MAUI conversion and stuck with the issue in Compatibility.Layout<T>, it doesn't display anything.

The MAUI project based on .NET 8.0 and Microsoft.Maui.Controls.Compatibility 8.0.21

I expect to see a label (the same code works on xamarin forms).

MAUI android lacks of the text label 
MAUI winui3 throw an exception
Xamarin forms android works fine
Xamarin forms uwp works fine

Maui and Xamarin code and screenshots are below.

What am I missing?

Here is my MAUI code (which doesn't work):

My custom layout control:

using Microsoft.Maui.Controls.Compatibility;

namespace MauiApp2
{
    public class CustomVerticalStackLayout : Layout<View>
    {
        private readonly Label lbl;

        public CustomVerticalStackLayout()
        {
            lbl = new Label { Text = "test", FontSize = 20, BackgroundColor = Colors.Red, HeightRequest = 100, WidthRequest = 100, Margin = 20 };

            Children.Add(lbl);

            BackgroundColor = Colors.Blue;
        }

        protected override Size MeasureOverride(double widthConstraint, double heightConstraint)
        {
            return new Size(200, 200);
        }

        protected override void LayoutChildren(double x, double y, double width, double height)
        {
            LayoutChildIntoBoundingRegion(lbl, new Rect(0, 0, 150, 150));
        }
    }

    public class CustomControl : ContentView
    {
        public CustomControl()
        {
            this.BackgroundColor = Colors.Green;

            this.Padding = new Thickness(30);
            this.Content = new CustomVerticalStackLayout();
        }

        protected override Size MeasureOverride(double widthConstraint, double heightConstraint)
        {
            return new Size(230, 230);
        }
    }
}

XAML:

<ContentPage xmlns=http://schemas.microsoft.com/dotnet/2021/maui
             xmlns:x=http://schemas.microsoft.com/winfx/2009/xaml
             x:Class="MauiApp2.MainPage"
             xmlns:c="clr-namespace:MauiApp2"
             BackgroundColor="Yellow"
             Padding="20">

    <c:CustomControl/>

</ContentPage>

MauiProgram:

            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .UseMauiCompatibility()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                });

Android result: no text label

enter image description here

Windows result: Throw an exception. (I think it's a different bug, I can reproduce it only on Windows)

The handler's MauiContext cannot be null. enter image description here

XAMARIN FORMS EXAMPLE

The very same code on the Xamarin Forms works fine.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace Xam
{
    public class CustomVerticalStackLayout : Layout<View>
    {
        private readonly Label lbl;

        public CustomVerticalStackLayout()
        {
            lbl = new Label { Text = "test", FontSize = 20, BackgroundColor = Color.Red, HeightRequest = 100, WidthRequest = 100, Margin = 20 };

            Children.Add(lbl);

            BackgroundColor = Color.Blue;
        }

        protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
        {
            return new SizeRequest(new Size(200, 200));
        }

        protected override void LayoutChildren(double x, double y, double width, double height)
        {
            LayoutChildIntoBoundingRegion(lbl, new Rect(0, 0, 150, 150));
        }
    }

    public class CustomControl : ContentView
    {
        public CustomControl()
        {
            this.BackgroundColor = Color.Green;

            this.Padding = new Thickness(30);
            this.Content = new CustomVerticalStackLayout();
        }

        protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
        {
            return new SizeRequest(new Size(230, 230));
        }
    }
}

I expected to see this. This is screenshots from the same code but on Xamarin Forms. enter image description here

here is my initial ask on https://stackoverflow.com/questions/78571366/maui-compatibility-layoutt-doesnt-display-anything

Steps to Reproduce

Please copy code snippets from Description

Link to public reproduction project repository

No response

Version with bug

8.0.20 SR4

Is this a regression from previous behavior?

Yes, this used to work in Xamarin.Forms

Last version that worked well

Unknown/Other

Affected platforms

Android, Windows

Affected platform versions

net8.0-windows10.0.19041.0, android14

Did you find any workaround?

Hi, I want to share update with my issue

I find the workaround for it; I must call explicitly .Measure( method for each child.

image

Relevant log output

No response

github-actions[bot] commented 1 month ago

Hi I'm an AI powered bot that finds similar issues based off the issue title.

Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one and thumbs upping the other issue to help us prioritize it. Thank you!

Open similar issues:

Closed similar issues:

Note: You can give me feedback by thumbs upping or thumbs downing this comment.