Search code examples
c#uwp-xamlcontroltemplatewinui-3

Put all CustomControl styles into Generic.xaml


I have created several CustomControls for using on my project. I have defined two projects:

  1. A ClassLibrary which contains my CustomControls.
  2. A WinUI application which uses ClassLibrary.

In the ClassLibrary I have created a custom control named Badge; Automatically visual studio defined a default Style with a sample Control Template for this Badge in Generic.xaml file under Themes folder.

I defined several Styles for this control. And I just put them into a file named BadgeStyle.xaml so I added this file as a MergedDictionary in Generic.xaml:

<ResourceDictionary xmlns:customControls="using:BSN.Kava.UI.SDK.CustomControls">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="ms-appx:///BSN.Kava.UI.SDK/CustomControls/BadgeStyle.xaml" />
    </ResourceDictionary.MergedDictionaries>    
    <Style TargetType="customControls:Badge" BasedOn="{StaticResource BadgeBase}" />
</ResourceDictionary>

I hoped that I'm able to use these Styles in my main WinUI3 application. But I can't. I should directly reference this BadgeStyle.xaml in App.xaml resource dictionary.

Surprisingly this line works (Without direct referencing to BadgeStyle.xaml in the app.xaml):

<Style TargetType="customControls:Badge" BasedOn="{StaticResource BadgeBase}" />

But the rest won't works.

Where is my problem?


Solution

  • Let's say you have a control library project called CustomControlsLibrary and your WinUI 3 app project has a reference to that library project.

    And in CustomControlsLibrary, you have a custom control CustomItem. Usually, you would have its template on:

    CustomControlsLibrary/Themes/Generic.xaml

    <Style TargetType="local:CustomItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:CustomItem">
                    <Button
                        Background="{TemplateBinding Background}"
                        Content="Default style" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    You also have additional styles for CustomItem in a seperate file:

    CustomControlsLibrary/Themes/CustomItemStyles.xaml

    <Style
        x:Key="CustomItemSkyBlueStyle"
        TargetType="local:CustomItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:CustomItem">
                    <Button
                        Background="SkyBlue"
                        Content="SkyBlue style" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
    <Style
        x:Key="CustomItemLightGreenStyle"
        TargetType="local:CustomItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:CustomItem">
                    <Button
                        Background="LightGreen"
                        Content="LightGreen style" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    In order to use the additional styles in you WinUI 3 app project, you need to declare it on App.xaml.

    App.xaml

    <Application
        x:Class="CustomControlStylesExample.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:CustomControlStylesExample">
        <Application.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
                    <!--  Other merged dictionaries here  -->
                    <ResourceDictionary Source="CustomControlsLibrary/Themes/CustomItemStyles.xaml" />
                </ResourceDictionary.MergedDictionaries>
                <!--  Other app resources here  -->
            </ResourceDictionary>
        </Application.Resources>
    </Application>
    

    Then, you'll be able to use it:

    <custom:CustomItem Style="{StaticResource CustomItemSkyBlueStyle}" />
    <custom:CustomItem Style="{StaticResource CustomItemLightGreenStyle}" />
    

    UPDATE

    If you are placing your additional styles in Generic.xaml:

    <ResourceDictionary.MergedDictionaries>
        <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
        <!--  Other merged dictionaries here  -->
        <ResourceDictionary Source="CustomControlsLibrary/Themes/Generic.xaml" />
    </ResourceDictionary.MergedDictionaries>