0

I am working on a MAUI windows application. I made a resource directory file for font.xaml in Resources\Styles and configured it in App.xaml.

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="ABC.Resources.Styles.Fonts">

    <x:Double x:Key="FontMicro">10</x:Double>
    <x:Double x:Key="FontSmall">14</x:Double>
    <x:Double x:Key="FontMedium">17</x:Double>
    <x:Double x:Key="FontLarge">24</x:Double>
    <x:Double x:Key="FontHeader">32</x:Double>
    <x:Double x:Key="FontTitle">28</x:Double>
    <x:Double x:Key="FontSubtitle">22</x:Double>
    <x:Double x:Key="FontCaption">12</x:Double>
    <x:Double x:Key="FontBody">16</x:Double>
    <x:Double x:Key="FontExtraLarge">70</x:Double>
</ResourceDictionary

I want to use this key in my application. I want to utilize it in a custom control. Can I directly use a static resource with a key?

<controls:ImageButtonControl Grid.Column="1" 
         CustomImageSource="white_200.png" 
         CustomText="STRENGTH&#x0a;TEST" 
         CustomFontSize="{StaticResource FontExtraLarge}"
         HeightRequest="250"
         Command="{Binding OnStrengthTestPageCommand}"/>

My Custom control.

<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ABC.Pages.Controls.ImageButtonControl"
             x:Name="imageButtonControl">
    <ContentView.Content>
        <Grid>
            <ImageButton Source="{Binding CustomImageSource, Source={x:Reference imageButtonControl}}" 
                   HorizontalOptions="Center"
                   VerticalOptions="Center"
                   BackgroundColor="Transparent"
                   BorderWidth="0"
                   Clicked="ImageButtonControl_Clicked"
                   Command="{Binding Command, Source={x:Reference imageButtonControl}}"/>
            <Label Text="{Binding CustomText, Source={x:Reference imageButtonControl}}" 
                   HorizontalOptions="Center" 
                   VerticalOptions="Center"
                   HorizontalTextAlignment="Center"
                   VerticalTextAlignment="Center"
                   TextColor="Black" 
                   InputTransparent="True"
                   FontSize="{Binding CustomFontSize, Source={x:Reference imageButtonControl}}" 
                   CharacterSpacing="{Binding CustomCharacterSpacing, Source={x:Reference imageButtonControl}}" 
                   FontFamily="{Binding CustomFontFamily, Source={x:Reference imageButtonControl}}"
                   FontAttributes="{Binding CustomFontAttribute, Source={x:Reference imageButtonControl}}"/>
        </Grid>
    </ContentView.Content>
</ContentView>

Is it necessary to define the target type (in my case, Label) and define all the fonts in Style.xaml like code below? I don't want to create a different style just to set a font size.

<Style TargetType="Label" x:Key="FontExtraLarge">
    <Setter Property="FontSize" Value="70" />
</Style>

I also tried DynamicResource, which is also not working.

2
  • In App.xaml, reference Fonts.xaml before Styles.xaml to ensure StaticResource and DynamicResource work correctly. You may have a Fonts.xaml.cs, but it isn’t necessary. Commented Nov 19 at 4:59
  • I think there is insufficient information to your question. We need to see more of your application to either (1) repro the DynamicResource problem, (2) understand what could be the cause. I would like to see your App.xaml and I would like an answer to why you appear to have a code-behind for your font.xaml. Commented 2 days ago

1 Answer 1

1

You're almost there.

You need to import your Resources\Styles\Font.xaml in your App.xaml:

  <Application.Resources>
    <ResourceDictionary>
      
      <ResourceDictionary.MergedDictionaries>  
        <ResourceDictionary Source="Resources/Styles/Font.xaml"/>
      </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
  </Application.Resources>
</Application>

Now you can define your custom control (This is just a small sample for you to check your custom control properties and bindings are ok):


<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="SampleApp.Controls.CustomControl"
             xmlns:controls="clr-namespace:SampleApp.Controls">
  <VerticalStackLayout Margin="0, 50, 0, 0">
    <Label
            FontSize="{Binding Source={RelativeSource AncestorType={x:Type controls:CustomControl}}, Path=CustomFontSize1, x:DataType=controls:CustomControl}"
            Text="This is custom fontsize 1"
            VerticalOptions="Center" 
            HorizontalOptions="Center" />

    <Label
            FontSize="{Binding Source={RelativeSource AncestorType={x:Type controls:CustomControl}}, Path=CustomFontSize2, x:DataType=controls:CustomControl}"
            Text="This is custom fontsize 2"
            VerticalOptions="Center" 
            HorizontalOptions="Center" />
  </VerticalStackLayout>
</ContentView>
namespace SampleApp.Controls;

public partial class CustomControl : ContentView
{
    public static readonly BindableProperty CustomFontSize1Property =
    BindableProperty.Create(
        propertyName: nameof(CustomFontSize1),
        returnType: typeof(double),
        declaringType: typeof(CustomControl),
        defaultValue: 12.5);

    public double CustomFontSize1
    {
        get
        {
            return (double)GetValue(CustomFontSize1Property);
        }

        set
        {
            SetValue(CustomFontSize1Property, value);
        }
    }

    public static readonly BindableProperty CustomFontSize2Property =
    BindableProperty.Create(
        propertyName: nameof(CustomFontSize2),
        returnType: typeof(double),
        declaringType: typeof(CustomControl),
        defaultValue: 12.5);

    public double CustomFontSize2
    {
        get
        {
            return (double)GetValue(CustomFontSize2Property);
        }

        set
        {
            SetValue(CustomFontSize2Property, value);
        }
    }

    public CustomControl()
    {
        InitializeComponent();
    }
}

Usage:

  <controls:CustomControl CustomFontSize1="{StaticResource FontMicro}" CustomFontSize2="{StaticResource FontExtraLarge}"/>

Result:

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the detailed answer. In my case, it doesn't work. If I assign static value like CustomFontSize="70, then it will work but, if I use CustomFontSize={StaticResource FontExtraLarge}", it will not work. It could be possible Somewhere from the global theme, it is overwritten. There is a theme defined in style.xaml for the target type label.
If it was the case of a style overwritting your Label, you would have had the same behaviour in both cases (binded value and static value). If it was the case of undeclared static resource, you would have gotten an exception. In your case, neither of those are happening. Double check your bindings & properties. I saw in your control you were not using {Binding Source={RelativeSource AncestorType={x:Type controls:CustomControl}}, Path=CustomFontSize1, x:DataType=controls:CustomControl}. If that doesn't work you should post your app.xaml and your ImageButtonControl.cs

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.