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

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).

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.

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}" />

Related

BitmapIconSource in a ResourceDictionary.ThemeDictionaries (UWP)

I would like to change the BitmapIcon of a NavigationViewItem depending on the current Windows theme.
I've added a ResourceDictionary.ThemeDictionaries to the MainPage like that:
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<BitmapIconSource x:Key="ProductionBitmap"
UriSource="/Assets/Images/ProduccioBlau.png" />
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<BitmapIconSource x:Key="ProductionBitmap"
UriSource="/Assets/Images/Produccio.png" />
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<BitmapIconSource x:Key="ProductionBitmap"
UriSource="/Assets/Images/Produccio.png" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Page.Resources>
And then in the NavigationViewItem:
<NavigationViewItem Content="Ordres fabricació"
Tag="OrdresFabricacio">
<NavigationViewItem.Icon>
<BitmapIcon UriSource="{ThemeResource ProductionBitmap}"
ShowAsMonochrome="False" />
</NavigationViewItem.Icon>
</NavigationViewItem>
But I get a squiggling line on UriSource="{ThemeResource ProductionBitmap}" saying:
The resource ProductionBitmap has an incompatible type.
What is the proper way to use a themed resource in this case?
The application compiles without errors, but I get an exception at run time when the themed resource is evaluated.
The issue is that you can't set the value of the UriSource property of the BitmapIcon in such a way. You could directly store the string value of the path of the image in the ResourceDictionary. Then using ThemeResource to get the string value.
Like this:
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<x:String x:Key="ProductionBitmap" >/Assets/london.png</x:String>
<!--<BitmapIconSource x:Key="ProductionBitmap" UriSource="/Assets/london.png" />-->
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<x:String x:Key="ProductionBitmap" >/Assets/paris.png</x:String>
<!--<BitmapIconSource x:Key="ProductionBitmap" UriSource="/Assets/paris.png" />-->
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<x:String x:Key="ProductionBitmap" >/Assets/paris.png</x:String>
<!--<BitmapIconSource x:Key="ProductionBitmap" UriSource="/Assets/paris.png" />-->
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Page.Resources>
Use it like this:
<BitmapIcon UriSource="{ThemeResource ProductionBitmap}" ShowAsMonochrome="False" />

Using a custom Library in an other custom library (Styles and Methodes)

I'm currently working on a personnal library (toolkit) to help me during my other projects.
Inside I have all my xaml style and some functions that I often use.
when I create a new application, I add my "toolkit" in the references and I add it in my app.xaml file like that :
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ToolKit;component/styles/global.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
With that, everything is working. I just got the following error "an error occurred while finding the resourcedictionary" but when I run it my styles are good.
But when I need to create a second custom library (to integrate it in revit) I don't have any success...
I tried this link but nothing is working. I get the same error "an error occurred while finding the resourcedictionary" and when I run it I don't have my styles...
I call the styles like that :
Style="{DynamicResource Borderless}"
and I got the error "the ressource Borderless could not be resolve"
My Toolkit have the namespace "ToolKit", a folder "Styles" and all the xaml inside this folder with a "Global.xaml" that merge all the dictionaries.
How can I get my styles applied ?
thank you
Edit :
Here is the DesignTimeResources.xaml to call the style :
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ToolKit;component/Styles/Global.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
and the Global.xaml look like this :
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ToolKit.Styles">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Windows.xaml" />
<ResourceDictionary Source="Borders.xaml" />
<ResourceDictionary Source="Buttons.xaml" />
<ResourceDictionary Source="CheckBox.xaml" />
<ResourceDictionary Source="Label.xaml" />
<ResourceDictionary Source="ListView.xaml" />
<ResourceDictionary Source="RadioButton.xaml" />
<ResourceDictionary Source="RichTextBox.xaml" />
<ResourceDictionary Source="ScrollBar.xaml" />
<ResourceDictionary Source="TextBlock.xaml" />
<ResourceDictionary Source="TextBox.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

The attachable property 'MergedDictionaries' was not found in type 'ResourceDictionary'

<Application x:Class="mahaapswpf.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<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>
</Application.Resources>
</Application>
I'm trying to use a MahApps.Metro Framework and I'm supposed to include this in my App.xaml, but I get "Nested properties are not supported: ResourceDictionaries.MergedDictionaries" error and "The attachable property "MergedDictionaries" was not found in type "ResourceDictionary".
I've tried everything but still can't fix this. Any idea? Thanks.
You're missing the tag that actually creates a ResourceDictionary instance:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
...
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>

VSTO Excel Add-In - WPF XAML Style issue

I am creating VSTO Office Excel-Add-In in which am popping up a simple WPF window. This window is styled with MahApps library. The issue is that no matter which approach I use, Icons while showing fine in the Visual Studio preview, during Debug they are missing. The Icons.xaml which is responsible for showing Icons is installed in Resources folder, with Build action set to Page. Any thoughts about this issue?
<Controls:MetroWindow.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 Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.AnimatedSingleRowTabControl.xaml" />
<ResourceDictionary Source="pack://application:,,,/ExcelAddIn;component/Resources/Icons.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Controls:MetroWindow.Resources>
I've tried also, without any success:
<ResourceDictionary Source="/ExcelAddIn;component/Resources/Icons.xaml" />
<ResourceDictionary Source="pack://application:,,,/component/Resources/Icons.xaml" />

Applying MahApps.Metro Dark theme

I am relatively new to WPF and I am trying to apply Windows Metro Dark theme to my entire application.
I used the following in my Apps.xaml and I can see the Windows Metro Light theme properly.
<Application.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>
</Application.Resources>
Now I want to change the theme to Dark. I understand I can always use,
ThemeManager.ChangeTheme()
But I believe there should be a way to do this with XAML effective to all the windows of the application.
My Question : Can someone point me how to do this without using ThemeManager in source code?
Try to use BaseDark instead of BaseLight. Try to change this line :
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
to this :
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" />
That did the trick for me. Screenshot of my application using MahApps BaseDark and BaseLight accents:
BaseDark
BaseLight

Categories