How to access the Styles.xaml file and use it in the c# markup code

70 Views Asked by At

I am new to dotnet maui and I can't figuring out how to use the styles defined in the Styles.xaml sheet in the c# markup code.

When I use the following code, my application crashes

new Label
{
    Text = "Hello, World!",
    Style = (Style)Application.Current.Resources["TitleLabel"]
}

The style exists in the stylesheet:

<Style TargetType="Label" x:Key="TitleLabel"\>
    <Setter Property="FontFamily" Value="Montserrat" /\>
    <Setter Property="FontSize" Value="20" /\>
    <Setter Property="FontAttributes" Value="None" /\>
    <Setter Property="TextColor" Value="{StaticResource Black}" /\>
</Style\>

So how do I get this style to work with my c# markup code?

2

There are 2 best solutions below

0
IV. On

More often, the Style is going to be consumed in the xaml which is fairly straightforward. For example, placing a label on the MainPage that uses the TitleLabel style could be expressed like this.

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="resources_from_code_behind.MainPage">

        <VerticalStackLayout
            Spacing="25"
            Padding="30,0"
            VerticalOptions="Center">

            <Label
                Style="{StaticResource TitleLabel}"
                Text="Hello, World!"
                FontSize="32"
                HorizontalOptions="Center" />

        </VerticalStackLayout>

</ContentPage>

However, your code seems to be attempting this in code-behind where the recipe might involve querying the MergedDictionaries collection and selecting the first one with Styles.xaml in its OriginalString property. I tested this and it works, but I can't say that I recommend it.

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent(); // <- Configures UI using description in xaml.

        if (Application
            .Current
            .Resources
            .MergedDictionaries
            .OfType<ResourceDictionary>()
            .FirstOrDefault(_ => 
                _.Source
                 .OriginalString
                 .Contains("Styles.xaml")) 
            is ResourceDictionary styles
            &&
            styles.TryGetValue("TitleLabel", out var obj)
            &&
            obj is Style style)
        {
            Label label = new Label
            {
                Style = style,
            };
            // Do something with label (this has not placed it anywhere so far.)
        }
    }
}
3
Liqun Shen-MSFT On

Styles can be defined globally by adding them to the app's resource dictionary. See Global styles. So you could put your TitleLabel in the app level.

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Resources/Styles/Colors.xaml" />
            <ResourceDictionary Source="Resources/Styles/Styles.xaml" />
        </ResourceDictionary.MergedDictionaries>
        <Style TargetType="Label" x:Key="TitleLabel">
            <Setter Property="FontFamily" Value="Montserrat" />
            <Setter Property="FontSize" Value="20" />
            <Setter Property="FontAttributes" Value="None" />
            <Setter Property="TextColor" Value="Black"/>
        </Style>
    </ResourceDictionary>
</Application.Resources>

Then you could get the style using your code without throwing the error,

new Label
{
    Text = "Hello, World!",
    Style = (Style)Application.Current.Resources["TitleLabel"]
}