I have resource dictionary files (MenuTemplate.xaml, ButtonTemplate.xaml, etc) that I want to use in multiple separate applications. I could add them to the applications' assemblies, but it's better if I compile these resources in one single assembly and have my applications reference it, right?
After the resource assembly is built, how can I reference it in the App.xaml of my applications? Currently I use ResourceDictionary.MergedDictionaries to merge the individual dictionary files. If I have them in an assembly, how can I reference them in xaml?
Check out the pack URI syntax. You want something like this:
<ResourceDictionary Source="pack://application:,,,/YourAssembly;component/Subfolder/YourResourceFile.xaml"/>
An example, just to make this a 15 seconds answer -
Say you have "styles.xaml" in a WPF library named "common" and you want to use it from your main application project:
Add a reference from the main project to "common" project
Your app.xaml should contain:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Common;component/styles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
I'm working with .NET 4.5 and couldn't get this working... I was using WPF Custom Control Library. This worked for me in the end...
<ResourceDictionary Source="/MyAssembly;component/mytheme.xaml" />
source: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/11a42336-8d87-4656-91a3-275413d3cc19
Resource-Only DLL is an option for you. But it is not required necessarily unless you want to modify resources without recompiling applications. Have just one common ResourceDictionary file is also an option. It depends how often you change resources and etc.
<ResourceDictionary Source="pack://application:,,,/
<MyAssembly>;component/<FolderStructureInAssembly>/<ResourceFile.xaml>"/>
MyAssembly - Just assembly name without extension
FolderStructureInAssembly - If your resources are in a folde, specify folder structure
When you are doing this it's better to aware of siteOfOrigin as well.
WPF supports two authorities: application:/// and siteoforigin:///.
The application:/// authority identifies application data files that
are known at compile time, including resource and content files. The
siteoforigin:/// authority identifies site of origin files. The scope
of each authority is shown in the following figure.
For UWP:
<ResourceDictionary Source="ms-appx:///##Namespace.External.Assembly##/##FOLDER##/##FILE##.xaml" />
Using XAML:
If you know the other assembly structure and want the resources in c# code, then use below code:
ResourceDictionary dictionary = new ResourceDictionary();
dictionary.Source = new Uri("pack://application:,,,/WpfControlLibrary1;Component/RD1.xaml", UriKind.Absolute);
foreach (var item in dictionary.Values)
{
//operations
}
Output: If we want to use ResourceDictionary RD1.xaml of Project WpfControlLibrary1 into StackOverflowApp project.
Structure of Projects:
Resource Dictionary:
Code Output:
PS: All ResourceDictionary Files should have Build Action as 'Resource' or 'Page'.
Using C#:
If anyone wants the solution in purely c# code then see my this
solution.
I know I will probably go to WPF hell but I like to keep it simple.
In my "external" WPF project named MyCorp.Wpf.Dll where I have a folder called assets with my resource dictionaries
MyCorp.Wpf.Dll
|- Assets
|- TextStyles.xaml
|- Colours.axml
Let's assume I have this TextStyles.xaml with the UI font styles that I need to apply because I need windows 10/ 11 style compliance
<Style x:Key="Header" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Sego UI Light"/>
<Setter Property="FontSize" Value="46" />
</Style>
<Style x:Key="Subheader" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Sego UI Light"/>
<Setter Property="FontSize" Value="32" />
</Style>
<Style x:Key="Title" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Sego UI SemiLight"/>
<Setter Property="FontSize" Value="24" />
</Style>
<Style x:Key="SubTitle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Sego UI Normal"/>
<Setter Property="FontSize" Value="20" />
</Style>
<Style x:Key="Base" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Sego Semibold"/>
<Setter Property="FontSize" Value="15" />
</Style>
<Style x:Key="Body" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Sego Normal"/>
<Setter Property="FontSize" Value="15" />
</Style>
<Style x:Key="Caption" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Sego Normal"/>
<Setter Property="FontSize" Value="12" />
</Style>
</ResourceDictionary>
These styles are in my corporate style guide and I am re-sing them al over the place
now in my brand new application I can use the corporate style DLL from an internal NuGet package feed or I link it because It happens to be in my solution using the following resource dictionary
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/MyCorp.Wpf;component/Assets/TextStyles.xaml"/>
<ResourceDictionary Source="/MyCorp.Wpf;component/Assets/Styles.xaml"/>
<ResourceDictionary Source="/MyCorp.Wpf;component/Assets/Brushes.xaml"/>
<ResourceDictionary Source="/MyCorp.Wpf;component/Assets/ColorStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
I have no clue where the extra component come from, I just know I needed. then in my new application I just link it like so:
<Application x:Class="MyNew.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>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ExternalResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<BooleanToVisibilityConverter x:Key="VisibilityConverter"/>
</ResourceDictionary>
</Application.Resources>
</Application>
This way I have all external links in the ExternalResources.xaml where everyone understands where they came from and updating them is easy
I can then use the external resource definitions like any other in my windows, page and controls
<syncfusion:ChromelessWindow x:Class="IDPS.ChromelessWindow1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:IDPS"
xmlns:r="clr-namespace:IDPS.Wpf.Properties;assembly=IDPS.Wpf"
xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
syncfusion:SfSkinManager.Theme="{syncfusion:SkinManagerExtension ThemeName=FluentDark}"
mc:Ignorable="d"
MinHeight="450" MinWidth="800">
<Grid>
<TextBlock Text="Hello world" Style="{StaticResource Title}"/>
</Grid>
</syncfusion:ChromelessWindow>
Related
I've integrated my WPF project into a mixed solution. This solution has 3 projects written in WinForms (.cs), 1 writtenin WinForms (.vb) and the mine one written in WPF (using MahApps).
The Owner of my project/windows must be the one of the three written in WinForm.
I've made a call like this:
using WPFSolution;
using System.Windows.Forms.Integration;
private void buttonOpenWPFUi_Click(object sender, EventArgs e)
{
var pm = new ProductsMenu();
ElementHost.EnableModelessKeyboardInterop(pm);
pm.Show();
}
ProductsMenu is my starting point on in the App.xaml
But when I reach the InitializeComponents() of the ProductsMenu.xaml.cs the System.Windows.Markup.XamlParseException were thrown
The error is: IOException: Cannot locate resource 'resources/icons.xaml'.
My App.xaml file:
<Application x:Class="WPFSolution.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="ProductsMenu.xaml" ShutdownMode="OnMainWindowClose">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! -->
<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/Controls.AnimatedTabControl.xaml" />
<!-- Accent and AppTheme setting -->
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Red.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
<!-- BaseDark.xaml | BaseLight.xaml -->
<!-- Icons -->
<ResourceDictionary Source="pack://application:,,,/WPFSolution;component/Resources/Icons.xaml"></ResourceDictionary>
<!-- Languages -->
<!--<ResourceDictionary Source="Resources/StringResources.en.xaml"></ResourceDictionary>-->
<ResourceDictionary Source="Resources/StringResources.it.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type ToolTip}">
<Setter Property="Background" Value="White"/>
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Padding" Value="7,4,7,4"/>
</Style>
<!--IMMAGINI -->
<!--nodi-->
<!--<BitmapImage x:Key="Nodo1" UriSource="Resources/img/TileImages/nodi/nodo1.jpg"></BitmapImage>
<BitmapImage x:Key="Nodo2" UriSource="Resources/img/TileImages/nodi/nodo2.jpg"></BitmapImage>
<BitmapImage x:Key="Nodo3" UriSource="Resources/img/TileImages/nodi/nodo3.jpg"></BitmapImage>
<BitmapImage x:Key="Nodo4" UriSource="Resources/img/TileImages/nodi/nodo4.jpg"></BitmapImage>-->
</ResourceDictionary>
</Application.Resources>
I've tried to set the Icons.xaml/Build Action as Resource and also as Page.
I'm missing something?
Got it (or a workaround at least).
I've dereferenced the WPFSolution Project.
Compiled the WPF solution
as .dll (I've copied all the merged dictionaries to every
window.xaml, removed the app.xaml file and change the application
type to class library)
Copied the WPFSolution.dll in the bin/release
- bin/debug of the main project
Referenced the .dll
Everything worked like a charm
try this syntax :
<ResourceDictionary Source="/WPFSolution;component/Resources/Icons.xaml" />
and also, "Page" is the right build option in this case
So I am trying to change the default font family and the font size in my project. I decided to start with buttons.
I do it like this (I am gonna create a separated file for my style, but now I just want to make it work somehow):
<Controls:MetroWindow.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Templates/MyTemplateSelector.xaml"/>
<ResourceDictionary Source="/Templates/FullMenu.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style BasedOn="{StaticResource MetroButton}" TargetType="Button">
<Setter Property="FontFamily" Value="Calibri" />
</Style>
</ResourceDictionary>
</Controls:MetroWindow.Resources>
and nothing changes. What is wrong?
I guess it's because program can't find "{StaticResource MetroButton}".
App.xaml
<Application x:Class="WpfApp2.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp2"
xmlns:dialogYesNo="clr-namespace:WpfApp2.DialogYesNo"
StartupUri="Views/MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! -->
<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" />
<!-- Accent and AppTheme setting -->
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
<ResourceDictionary Source="ViewModels.xaml" />
<ResourceDictionary Source="Dialogs.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
So, you just need to use it in App.xaml after declaring metro references:
<Style TargetType="Label">
<Setter Property="FontFamily" Value="Segoe UI Light"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI Light"/>
</Style>
<Style TargetType="TextBox">
<Setter Property="FontFamily" Value="Segoe UI "/>
</Style>
Button uses TextBox, so button will be changed automatically.
Instead of define a style just to set fontfamily/weight you can just define in your resource directly the fontfamily and weight with a key(an example with a font that i use)
<Controls:MetroWindow.Resources>
<FontFamily x:Key="FontAwesome">/tuseradm;component/assets/fontawesome-webfont.ttf#FontAwesome</FontFamily>
</Controls:Flyout.Resources>
then in your button just set the font family
<Button FontFamily="{StaticResource FontAwesome}" Content="" />
EDIT adding another answer:
by default mahapps override the default wpf style. If you want to modify a style for let's say buttons in all your view you don't need to use based on
<Style BasedOn="{StaticResource {x:Type Button}}" TargetType="Button">
<Setter Property="FontFamily" Value="Calibri" />
<Setter Property="FontWeight" Value="ExtraLight"/>
</Style>
EDIT 2
At least for me, even if i see the change at design time using the approach exposed in the first edit, at run time the problem persist. So in my opinion, is much better to stick with my first answer. Maybe it could be annoying to set fontfamily and fontweight for each button, but it is the safest way to deal with mahapps styles. The only way to solve this 100% for sure is to find (no clue where) the template of mahapps buttons and modify it
Below you can see how I am trying to segregate styles by merging dictionaries (I'm skipping namespaces for the sake of cleanliness)
App.xaml:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Style/Colors.xaml" />
<ResourceDictionary Source="Style/HeaderStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Colors.xaml:
<SolidColorBrush x:Key="DarkTextForeground" Color="#7471b9"/>
HeaderStyle.xaml:
<Style x:Key="HeaderTextBlockStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource DarkTextForeground}"/>
<Setter Property="FontWeight" Value="Black"/>
</Style>
During compilation I get a following error:
Cannot find a Resource with the Name/Key DarkTextForeground
To make It work we have to merge Colors.xaml inside HeaderStyle.xaml like this:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Colors.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="HeaderTextBlockStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource DarkTextForeground}"/>
<Setter Property="FontWeight" Value="Black"/>
</Style>
Can anyone explain to me, why I have to reference Colors.xaml in HeaderStyle.xaml? Can't I just reference styles defined in different merged dictionary?I assume that Colors.xaml is loaded before HeaderStyle.xaml so it should be visible for dictionaries defined later.
This is a response to my question from Erick Fleck at msdn forums:
In your first example each file is parsed independently and then added to the merged dictionary so they don't know anything about each other...similarly, the XAML in a merged dictionary cannot reference names in the 'parent' ResourceDictionary. In other words, you should think of a MergedDictionaries as a one-way reference.
It's the way It works I guess...
I have a Resources.xaml file in my project that contains a resource dictionary like so:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="GPHeaderFontSize" TargetType="TextBlock">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="FontSize" Value="24" />
<Setter Property="Text" Value="BLAHHHHH"/>
</Style>
</ResourceDictionary>
I have included this dictionary in App.xaml like so:
<Application x:Class="GoldenPlains.App"
xmlns="schemas.microsoft.com/winfx/2006/xaml/presentation";
xmlns:x="schemas.microsoft.com/winfx/2006/xaml";
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone">
<Application.Resources>
<local:LocalizedStrings xmlns:local="clr-namespace:GoldenPlains" x:Key="LocalizedStrings"/>
<ResourceDictionary x:Key="GPResources">
<ResourceDictionary.MergedDictionaries>
<!-- Sometimes VS2012 complaining about path with blue line, please ignore it as path is correct -->
<ResourceDictionary Source="Styles/GPResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="GPRootOverlayBarStyle" TargetType="Image">
<Setter Property="Source" Value="Assets/Images/root_brown_horizontal_bar.png"/>
<Setter Property="Width" Value="729"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Stretch" Value="Uniform"/>
</style>
</Application.Resources>
...
...
</Application>
However when I try to reference an element in the resource dictionary from another Page.xaml file it cannot seem to resolve the resource....
eg:
I have tried using a binding like so:
<TextBlock Style="{Binding Path=LocalizedResources.MyTextBlockStyle, Source= {StaticResource GPResources}}"/>
it does not indicate that something is wrong but nothing shows up on the UI.
A point in the right direction would be great, cheers.
Resource Dictionary definition in the App.xaml should be about like following example :
<Application.Resources>
<ResourceDictionary>
<local:LocalizedStrings xmlns:local="clr-namespace:GoldenPlains" x:Key="LocalizedStrings"/>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/GPResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<!-- Other resources if you have -->
</ResourceDictionary>
</Application.Resources>
Then, when you need to apply style defined in Resources.xaml to a UI control, simply refer to the style's key/name :
<TextBlock Style="{StaticResource GPHeaderFontSize}" />
Notes: All resources need to be inside ResourceDictionary tag, including LocalizedStrings.
I am working on a Windows Phone 8 project, project was created using C# Windows Phone Blank App from templates, I have added a simple ResourceDictionary entitled GPResources.xaml(manually created) and then referenced that file in App.xaml, the file I created is located in the root folder, code below:
<!-- VS2012 saying FontFamily and FontSize properties are not recognized or are not accessable, not sure why... ANYONE?-->
<Style TargetType="{StaticResource GPFontFamily}">
<Setter Property="FontFamily" Value="CalifR.ttf"/>
</Style>
<Style TargetType="{StaticResource GPFontSizeSmall}">
<Setter Property="FontSize" Value="12"/>
</Style>
<Style TargetType="{StaticResource GPFontSizeMedium}">
<Setter Property="FontSize" Value="18"/>
</Style>
<Style TargetType="{StaticResource GPFontSizeLarge}">
<Setter Property="FontSize" Value="22"/>
</Style>
App.Xaml:
<ResourceDictionary x:Key="GPResources">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="GPResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
VS2012 keeps giving me the error: "An Error occurred while finding the resource dictionary" in the App.xaml file, I cannot think of what the problem is, can anyone point me in the right direction?
Cheers
I think you created Resource Dictionary in a wrong way. Following is an example on how to define a style named "GPTextBlock" that will style a TextBlock where it applied, to have a FontSize = 12 and displaying text in Red color.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="TextBlock" x:Key="GPTextBlock">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="FontSize" Value="12"/>
</Style>
<Style ...>
...
...
</Style>
....
....
</ResourceDictionary>
And overall structure of GPResources.xaml content you had should look like above sample structure. This is one of resources I found explaining about ResourceDictionary you may want to take a look : MSDN Blog