Advertisement
Advertisement

In this post, I show how display HTML with NET8 MAUI Label using only the Label attributes. The source code of this post is available on GitHub.

Scenario

For my app, I want to display a sentence. Part of this sentence can be in bold or italics. So, I started to create an example using FlexLayout. First, I created a ContentView called FormattedMessage with this XAML:

<?xml version="1.0" encoding="utf-8" ?>
<ContentView
	x:Class="MauiTest.FormattedMessage"
	xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
	xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">

	<FlexLayout
		BindableLayout.ItemsSource="{Binding FormattedText}"
		HorizontalOptions="FillAndExpand"
		VerticalOptions="FillAndExpand">
		<BindableLayout.ItemTemplate>
			<DataTemplate>
				<Label
					Padding="10"
					FontAttributes="{Binding FontAttributes}"
					Text="{Binding Text}"
					TextColor="{Binding TextColor}" />
			</DataTemplate>
		</BindableLayout.ItemTemplate>
	</FlexLayout>
</ContentView>

Code behind

Then, in the code for this view, I added the binding property

Advertisement
using MauiTest.Extensions;
using MauiTest.Models;

namespace MauiTest;

public partial class FormattedMessage : ContentView
{
	public IList<FormattedText>? FormattedText { get; set; }

	public static readonly BindableProperty MessageProperty = 
		BindableProperty.Create(nameof(Message), typeof(IList<FormattedText>), 
			typeof(FormattedMessage), null);

	public string Message
	{
		get => (string)GetValue(MessageProperty);
		set
		{
			SetValue(MessageProperty, value);
            FormattedText = value.GetFormattedMessage();
			OnPropertyChanged(nameof(FormattedText));
        }
	}

	public FormattedMessage()
	{
		InitializeComponent();
		BindingContext = this;
	}
}

FormattedText model

Now, each part of the sentence I want to display has to be define using this model

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

namespace MauiTest.Models
{
    /// <summary>
    /// Class FormattedText.
    /// </summary>
    public class FormattedText
    {
        /// <summary>
        /// Gets or sets the font attributes.
        /// </summary>
        /// <value>The font attributes.</value>
        public FontAttributes FontAttributes { get; set; } = FontAttributes.None;

        /// <summary>
        /// Gets or sets the text.
        /// </summary>
        /// <value>The text.</value>
        public string? Text { get; set; }

        /// <summary>
        /// Gets or sets the color of the text.
        /// </summary>
        /// <value>The color of the text.</value>
        public Color TextColor { get; set; } = Colors.Black;
    }
}

String Extension

I split the string in chunks. I defined that when I find a star *, I want that part of the string in bold. Using RegEx, I split the string and add the part of the string to the IList<FormattedText>.

using MauiTest.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace MauiTest.Extensions
{
    public static class StringExtensions
    {
        public static IList<FormattedText> GetFormattedMessage(this string message)
        {
            List<FormattedText> Result = new List<FormattedText>();
            string pat = @"\*([^\*]*)\*|([^*]+)";
            Match match = Regex.Match(message, pat);
            while (match.Success)
            {
                if (match.Groups[1].Success)
                {
                    Result.Add(new FormattedText() { Text = match.Groups[1].Value, 
                        FontAttributes = FontAttributes.Bold });
                }
                if (match.Groups[2].Success)
                {
                    Result.Add(new FormattedText() { Text = match.Groups[2].Value, 
                        FontAttributes = FontAttributes.None });
                }
                match = match.NextMatch();
            }
            return Result;
        }
    }
}

Put together

Now, putting everything together, the result is not what I expected.

FlexLayout is not rendering the words in the correct way. As a test, I change FlexLayout with a VerticalLayout and I can see every part of the sentence with the correct attributes

Solution

I didn’t know that now Label has a new attribute TextType and I can pass HTML code

<Label 
    Text="Lorem ipsum dolor sit amet, &lt;b>consectetur adipiscing elit&lt;/b>." 
    TextType="Html" />

The only thing is to replace the char < with &lt;. Also, it is possible to add this code

<Label TextType="Html">
    <![CDATA[
        <p>Este es el primer párrafo con <u>texto subrayado</u>.</p>
        <p>segundo párrafo, donde parte del <del>texto está tachado</del>.</p>
    ]]>
</Label>

From the C#, I can write

Label label = new Label
{
    TextType = TextType.Html,
    Text = "<p>Este es el primer párrafo con <u>texto subrayado</u>.</p>" +
      "<p>segundo párrafo, donde parte del <del>texto está tachado</del>.</p>"
};

I hope this can help someone. Happy coding!

Advertisement

By Enrico

My greatest passion is technology. I am interested in multiple fields and I have a lot of experience in software design and development. I started professional development when I was 6 years. Today I am a strong full-stack .NET developer (C#, Xamarin, Azure)

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.