Search code examples
xamarin.formsxamarin.forms-styles

Adding a style to a class defined in a custom UI library


Currently I am working on a UI Library which is supposed to contain custom UI Elements, Layouts and Dialogs in order to have a consistent and reusable UI collection.

In my project, the current structure is as follows:

  • UILib (Shared Code for the library)
  • UILib.Droid (android library containing custom renders, etc.)
  • UILib.iOS (iOS library containing custom renderers, etc.)
  • UILibDemo (Shared Code for demo application consuming the library)
  • UILibDemo.Droid (demo application Android)
  • UILibDemo.iOS (demo application iOS)

In my library I have a class "LoadingDialog", which works fine so far. However my problem is that I am now trying to define a style to change some properties of the LoadingDialog from within the shared code of the demo application (App.xaml):

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:dialogs="clr-namespace:UILib.Dialogs;assembly=UILib"
         x:Class="BetterUIDemo.App">
<Application.Resources>
    <ResourceDictionary>
        <x:String x:Key="DefaultFontLight">OpenSans-Light.ttf</x:String>
        <Color x:Key="ThemeColor">#f08c00</Color>
        <Color x:Key="BackgroundColor">#37474f</Color>

        <Style x:Key="LoadingDialogStyle" TargetType="dialogs:LoadingDialog">
            <Setter Property="ThrobberBackgroundColor" Value="White" />
            <Setter Property="LabelFontFamily" Value="{DynamicResource DefaultFontLight}" />
            <Setter Property="LabelColor" Value="{DynamicResource ThemeColor}" />
            <Setter Property="LoadingText" Value="Lade Daten ..." />
        </Style>
    </ResourceDictionary>
</Application.Resources>

My LoadingDialog class contains these properties as well:

#region Properties
    public static BindableProperty ThrobberBackgroundColorProperty = BindableProperty.Create("ThrobberBackgroundColor", typeof(Color), typeof(Color), Color.Black);
    public static BindableProperty FontFamilyProperty = BindableProperty.Create("FontFamily", typeof(string), typeof(string), Font.Default.FontFamily);
    public static BindableProperty LabelColorProperty = BindableProperty.Create("LabelColor", typeof(Color), typeof(Color), Color.Black);
    public static BindableProperty LoadingTextProperty = BindableProperty.Create("LoadingText", typeof(string), typeof(string), "Loading ...");

    public string LabelFontFamily
    {
        get { return (string)GetValue(FontFamilyProperty); }
        set { SetValue(FontFamilyProperty, value); }
    }

    public Color ThrobberBackgroundColor
    {
        get { return (Color)GetValue(ThrobberBackgroundColorProperty); }
        set { SetValue(ThrobberBackgroundColorProperty, value); }
    }

    public string LoadingText
    {
        get { return (string)GetValue(LoadingTextProperty); }
        set { SetValue(LoadingTextProperty, value); }
    }

    public Color LabelColor
    {
        get { return (Color)GetValue(LabelColorProperty); }
        set { SetValue(LabelColorProperty, value); }
    }

    #endregion

However when I try to compile the demo app, I get the following error:

Severity Code Description Project File Line Suppression State Error Position 14:13. Can't resolve LabelFontFamily on LoadingDialog UILibDemo C:\Work\UILib\UILibDemo\UILibDemo\App.xaml 14

Any suggestions what I might be doing wrong?


Solution

  • I think this could just be a naming thing causing your error.

    Bindable Properties use some "Magic" where the Property name and the bindable property need to be named the same thing but the bindable property has the word Property on the end

    Notice how your BindableProperty is just called FontFamily

    Changing it to the below should fix your error

    public static BindableProperty LabelFontFamilyProperty = BindableProperty.Create("LabelFontFamily", typeof(string), typeof(string), Font.Default.FontFamily);
    
    public string LabelFontFamily
    {
       get { return (string)GetValue(FontFamilyProperty); }
       set { SetValue(FontFamilyProperty, value); }
    }