Multiple lines in a Label with FormattedString showing inconsistent behaviour between Windows and Android [.NET MAUI]

Robbie Ridgway 0 Reputation points
2024-06-15T05:55:10.3+00:00

Hi,

I've been working on a hobbyist project to create and roll custom dice rolls, which are then displayed using a PopUp.. I'm having an issue with how the Label (using FormattedString to create a series of spans showing the text.

The XAML code for the popup is:

<?xml version="1.0" encoding="utf-8" ?>
<toolkit:Popup 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"
             Color="Transparent"
             x:Class="Pathfinder_1e_Assistant.Popups.PopupMacro"
             x:Name="MacroCard"
             >

    <VerticalStackLayout 
        VerticalOptions="Center"
        HorizontalOptions="Center"
        x:Name="MacroControl"
        >
        <Frame BackgroundColor="Black">
            <Label
            x:Name="MacroLabel"
            LineBreakMode="NoWrap"
        />
        </Frame>
    </VerticalStackLayout>
</toolkit:Popup>

The code I'm using for the Popup window looks like this:

using CommunityToolkit.Maui.Views;
using System.Diagnostics;
namespace Pathfinder_1e_Assistant.Popups;
 
public partial class PopupMacro : Popup
{
	// For rolls
	readonly Color bgColor = Colors.Yellow;
    readonly Color critHitColor = Colors.Green;
    readonly Color critFailColor = Colors.Red;
    readonly Color rollColor = Colors.Black;
	readonly Color textColor = Colors.White;
    readonly Color regularColor = Colors.Transparent;
    public PopupMacro(string[] macroSnippets, int[] critFlags)
	{
		InitializeComponent();
		FormattedString formattedString = new();
		for (int i = 0; i < macroSnippets.Length; i++)
		{
			Span span = new() { Text = macroSnippets[i] };
			
			switch (critFlags[i]) 
			{
				case 0: // Regular roll, no crit
					span.BackgroundColor = bgColor;
					span.FontAttributes = FontAttributes.Bold;
					span.TextColor = rollColor;
					break;
				case 1: // Critical Hit!
                    span.BackgroundColor = critHitColor;
                    span.FontAttributes = FontAttributes.Bold;
                    span.TextColor = rollColor;
                    break;
				case -1: // Critical Fail!
					span.BackgroundColor = critFailColor;
                    span.FontAttributes = FontAttributes.Bold;
                    span.TextColor = rollColor;
                    break;
                case 2: // Text
					span.BackgroundColor = regularColor;
                    //span.FontAttributes = FontAttributes.Bold;
                    span.TextColor = textColor;
                    break;
            }
			formattedString.Spans.Add(span);
		}
		MacroLabel.FormattedText = formattedString;
	}
}

On Windows, I get the expected behaviour, looking like this:

User's image

On Android, it looks like this:

2024-06-14 23.42.07.jpg

If I adjust the size of the Popup, it des respect that, but only shows the first line as before:

My initial thought is that FormattedString isn't working correctly on Android (or at least my device) with multiple spans. Is there something I need to do differently?

.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,834 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Robbie Ridgway 0 Reputation points
    2024-06-15T06:50:25.6066667+00:00

    I have found a solution, but it feels like a workaround rather than a solution.

    If I delete the frame from the XAML page, and replace MacroLabel.FormattedText = formattedString; with the following:

    Frame frame = new() 
    { 
    	BackgroundColor = bgLabelColor,
        Content = new Label { FormattedText = formattedString, BackgroundColor = bgLabelColor }
    };
    MacroControl.Children.Add(frame);
    

    Then I get the behaviour I was expecting.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.