Maui icon indicating copy to clipboard operation
Maui copied to clipboard

[BUG] StateView is not able to present correctly in some layout

Open BrandonStudio opened this issue 1 year ago • 5 comments
trafficstars

Is there an existing issue for this?

  • [X] I have searched the existing issues

Did you read the "Reporting a bug" section on Contributing file?

  • [X] I have read the "Reporting a bug" section on Contributing file: https://github.com/CommunityToolkit/Maui/blob/main/CONTRIBUTING.md#reporting-a-bug

Current Behavior

A simplified document tree is shown below

<container>
  <stateViewItems />
  <staticItems />
</container>

When container is one of [Grid, StackLayout], stateViewItems is correctly shown. When container is one of [ContentView, Frame, ScrollView],

  • on Windows: An exception is thrown from App.g.i.cs
  • on Android: Only staticItems is shown

Expected Behavior

stateViewItems is correctly shown whatever container is.

Steps To Reproduce

XAML:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             xmlns:local="clr-namespace:MauiLayout.NW"
             x:Class="MauiLayout.NW.NewPage1">

    <ContentPage.BindingContext>
        <local:StateContainerViewModel />
    </ContentPage.BindingContext>

    <ScrollView 
        x:Name="vsl"
        toolkit:StateContainer.CurrentState="{Binding CurrentState}"
        toolkit:StateContainer.CanStateChange="True">
        <toolkit:StateContainer.StateViews>
            <Label Text="loading" toolkit:StateView.StateKey="Loading" />
            <Label Text="Success" toolkit:StateView.StateKey="Success" />
        </toolkit:StateContainer.StateViews>
        <Label x:Name="lbl" Text="Default Content" />
    </ScrollView>
</ContentPage>

C#:

using System.ComponentModel;

namespace MauiLayout.NW;

public partial class NewPage1 : ContentPage
{
	public NewPage1()
	{
		InitializeComponent();
	}
}

public enum States
{
	Loading,
	Success
}

public partial class StateContainerViewModel : INotifyPropertyChanged
{
	public StateContainerViewModel()
	{
		_changeStateCommand = new(ChangeState);
	}

	States currentState = States.Loading;
	public States CurrentState
	{
		get => currentState;
		set
		{
			currentState = value;
			PropertyChanged?.Invoke(this, new(nameof(CurrentState)));
		}
	}

	public event PropertyChangedEventHandler? PropertyChanged;

	void ChangeState()
	{
		CurrentState = States.Success;
	}

	Command _changeStateCommand;

	public Command ChangeStateCommand => _changeStateCommand;
}

Link to public reproduction project repository

see code above

Environment

  • .NET MAUI CommunityToolkit: 7.0.1
  • OS: Windows
  • .NET MAUI: 8.0.6

Anything else?

I get the error message on Windows: e.Message: Cannot create the StateContainerController. The specified view 'Microsoft.Maui.Controls.ScrollView' does not inherit Layout.

It's so weird Why your sample works but mine doesn't?

BrandonStudio avatar Jan 25 '24 08:01 BrandonStudio

Why your sample works but mine doesn't?

Our sample has a <VerticalStackLayout> inside the Content of the ScrollView. The error could be a little more helpful but it looks like your content needs to be a Layout. So any of these basically. A ScrollView is not a Layout control.

bijington avatar Jan 25 '24 09:01 bijington

it looks like your content needs to be a Layout. So any of these basically. A ScrollView is not a Layout control.

@bijington I notice that tk:DockLayout etc. can be the container. So what is exactly "a Layout control"? It sounds like a control whose class is derived from Layout, which is actually not correct because ScrollView does be derived from Layout. And it seems that it is not mentioned in the documentation

BrandonStudio avatar Feb 02 '24 02:02 BrandonStudio

A Layout is something that inherits from Layout as you have pointed out. Now interestingly while ScrollView does inherit from a class called Layout it is actually Compatibility.Layout and this is not the same as Layout.

I am only on my phone so I haven't been able to answer all of my own current questions:

  1. What is the difference between these two base classes
  2. What we need from Layout that we use for StateLayout

bijington avatar Feb 04 '24 17:02 bijington

I see. Can I assume that the type of container that can host stateViewItems can be and must be a subclass of Microsoft.Maui.Controls.Layout, namely one of AbsoluteLayout, FlexLayout, Grid, StackBase, and DockLayout and UniformItemsLayout from CommunityToolkit?

By the way, it seems that FlexLayout is very special, whose manager is not derived from Microsoft.Maui.Controls.LayoutManager, is it compatible to be the container?

BrandonStudio avatar Feb 05 '24 04:02 BrandonStudio

Based on this description in our docs I would say yes to your first question.

As for the specifics around FlexLayout using a different base class for its LayoutManager implementation, I can't see where we explicitly use the LayoutManager in our code that would make this distinction important. If you want to use it I would suggest trying it and see.

bijington avatar Feb 05 '24 06:02 bijington

It appears the questions have been answered and clarified about the Layouts. I am closing this issue since no more information is required at the moment. If needed we can re-open it again.

vhugogarcia avatar Jul 23 '24 17:07 vhugogarcia