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 FlexLayou
t. 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
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, <b>consectetur adipiscing elit</b>."
TextType="Html" />
The only thing is to replace the char <
with <
. 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!