user6416335
user6416335

Reputation:

WPF style not applying at runtime (but works in designer)

I have this code in WPF window:

<Window.Resources>
    <Style x:Key="MahappsStyle">
        <Style.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
                    <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
                    <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
                    <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
                    <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </Style.Resources>
    </Style>
</Window.Resources>

The idea is to enable external styles in dictionary for single elements in my application. For example, it should work by applying style "MahappsStyle" to element called "HamburgerMenu":

<mahapps:HamburgerMenu x:Name="hamburgerMenu" Style="{StaticResource MahappsStyle}"
                    DisplayMode="CompactOverlay">
</mahapps:HamburgerMenu>

But this approach seems to be working only in designer, but not at runtime. What am I missing? Is there any other way to set MergedDictionaries to a single element?

UPDATE. Found the way to do that. First need to create Mahapps.xaml in application with following content:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
                    xmlns:local="clr-namespace:Promt.Desktop">

    <ResourceDictionary.MergedDictionaries >
        <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml"/>
        <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
        <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
        <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
        <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

And then it is possible to apply to single element by:

<mahapps:HamburgerMenu>
            <mahapps:HamburgerMenu.Resources>
                <ResourceDictionary Source="pack://application:,,,/Promt.Desktop;component/Styles/Mahapps.xaml"/>
            </mahapps:HamburgerMenu.Resources>
</mahapps:HamburgerMenu>

I'm really disappointed that ResourceDictionary can't hold x:key property. If anyone knows another approach - please post it.

UPDATE2. Even better solution from Evk (based on Laith answer).

Upvotes: 4

Views: 1383

Answers (2)

Evk
Evk

Reputation: 101643

Laith answer is close but not completely there, you need to do it this way:

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary x:Key="MahappsResources">
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </ResourceDictionary>
</Window.Resources>

And then you can indeed reference by key:

<mahapps:HamburgerMenu Resources="{StaticResource MahappsResources}" />

You need to add one more ResourceDictionary definition because otherwise it treats your MahappsResources as Window.Resources (so analog to Window.Resources = new ResourceDictionary() ...) and setting key on it indeed makes no sense. When you add one more ResourceDictionary - now you are indeed adding your MahappsResources to Window.Resources dictionary, with given key, and so can reference it by that key.

Upvotes: 2

Laith
Laith

Reputation: 6091

Can you check if this works:

<Window.Resources>
    <ResourceDictionary x:Key="MahappsResources">
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>

and your controls can reference it using the key:

<mahapps:HamburgerMenu Resources="{StaticResource MahappsResources}" />

Upvotes: 1

Related Questions