This question already has answers here:
ResourceDictionary in separate library
(3 answers)
Sharing WPF-Dictionary from another assembly
(1 answer)
Closed 3 years ago.
For a Revit plugin I'm building a WPF dialog, with a view, logic, and now some styling.
Very quickly I came to the conclusion that putting all my styling in the is really messy (it just means I'm scrolling through my XAML half of my time). So I wanted to split my styling from my XAML code (like you would with HTML and CSS).
So I found out about the and how I should go about setting it up. I have my window, with this resource code:
<Window.Resources>
<local:LocationView x:Key="mainViewDataSource" />
<FontFamily x:Key="Ubuntu">pack://application:,,,/Kalec.Enveo;component/src/Resources/Fonts/#Ubuntu</FontFamily>
<FontFamily x:Key="FontAwesomeSolid">pack://application:,,,/Kalec.Enveo;component/src/Resources/Fonts/#Font Awesome 5 Free Solid</FontFamily>
<FontFamily x:Key="FontAwesomeRegular">pack://application:,,,/Kalec.Enveo;component/src/Resources/Fonts/#Font Awesome 5 Free Regular</FontFamily>
<ResourceDictionary x:Key="dictionary" Source="pack://application:,,,/Kalec.Enveo;component/src/WPF/Styles/Dictionary.xaml" />
</Window.Resources>
And my Dictionaries:
Dictionary.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary x:Key="MergedDictionaries">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionaries/InputStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
and InputStyles.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="SearchInputStyle" TargetType="{x:Type TextBox}">
<Setter Property="Height" Value="30"/>
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border CornerRadius="15" Background="White" BorderBrush="Transparent" x:Name="border">
<Grid>
<TextBox Text="{Binding Path=Text,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
x:Name="textSource"
Background="Transparent"
Panel.ZIndex="2" />
<TextBox Text="{TemplateBinding Tag}" Background="{TemplateBinding Background}" Panel.ZIndex="1">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="Transparent"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Text, Source={x:Reference textSource}}" Value="">
<Setter Property="Foreground" Value="Gray"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="Red"/>
<Setter Property="Foreground" Value="Red" />
</Trigger>
<Trigger Property="IsFocused" Value="true">
<Setter Property="Foreground" Value="Blue" />
<Setter Property="BorderBrush" TargetName="border" Value="Blue"/>
</Trigger>
<DataTrigger Binding="{Binding Path=Text}" Value="">
<Setter Property="Text" Value="Vul een adres in"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The problem is that I can't seem to use the style on my textBox:
<StackPanel Margin="10,10,0,0" Orientation="Vertical">
<StackPanel Panel.ZIndex="10" Orientation="Horizontal"
Name="SearchParameters"
>
<TextBox Width="220" Style="{DynamicResource SearchInputStyle}"/>
<Button FontFamily="{StaticResource FontAwesomeSolid}"
Content="" Foreground="#31B192" Grid.ColumnSpan="2"
Style="{DynamicResource LocationImport}"
Margin="10, 0, 0, 0"/>
</StackPanel>
I simply get the error that it could not be resolved. I looked at some solutions, and most of them tell me to include the ResourceDictionary in my App.xaml, but I don't have that file, because my project is a class library (it's a requirement for the plugin).
Can I even use Resource Dictionaries? Or is there some other way to seperate the styling or XAML in different files?
I guess you got the correct ingredients but not the correct recipe.
Here's how its working for me:
I have a class library project which defines all my styles (ControlLibrary in the image)
Here is one Button styles ResourceDictionary
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp1">
<Style x:Key="RedButton" TargetType="Button">
<Style.Setters>
<Setter Property="Background" Value="Red"/>
</Style.Setters>
</Style>
<Style x:Key="GreenButton" TargetType="Button">
<Style.Setters>
<Setter Property="Background" Value="Green"/>
</Style.Setters>
</Style>
</ResourceDictionary>
Then Here's is the single point of contact for all individual styles. Dictionary.xaml
(Note that this is using MergedDictionary)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp1">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="./Styles/ButtonStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Finally to use the Styles from ClassLibrary dll into my WpfApp project (after adding reference to it) we again use MergedDictionaries..!!
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/ControlLibrary;component/Dictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
Related
I have some styles and templates in App.Xaml so I can acces them thru multiple UserControls.
EDIT : This is within the app.Xaml:
One of the Styles are :
<Application x:Class="BaseRefence.generatingAnnotation.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BaseRefence.generatingAnnotation"
xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="ComboBoxStyleRounded" TargetType="{x:Type ComboBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Border CornerRadius="25"
BorderThickness="1,1,2,2">
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource ComboBox.Static.Background}"/>
<Setter Property="BorderBrush" Value="#42536b"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderThickness" Value="1,1,2,2"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="Padding" Value="6,3,5,3"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template" Value="{StaticResource ComboBoxTemplate}"/>
<Style.Triggers>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Padding" Value="2"/>
<Setter Property="Template" Value="{StaticResource ComboBoxEditableTemplate}"/>
</Trigger>
</Style.Triggers>
</Style>
</Application.Resources>
</Application>
And in de UserControl.Xaml I have:
<ComboBox ItemsSource="{Binding ViewFamilyTypesInProject}"
SelectedItem="{Binding SelectedViewFamilyType, Mode=TwoWay}"
Grid.Row="1"
Grid.Column="1"
Margin="10 5"
MaxHeight="40"
Style="{DynamicResource ComboBoxStyleRounded}">
Within the designer everything works great, it shows correctly and all.
However, whenever I build and run my code, it gives the message and it does not override the style but keeps the default style.
System.Windows.ResourceDictionary Warning: 9 : Resource not found; ResourceKey='ComboBoxStyleRounded'
My experience: I frequently have same issues (using VS 16.6.2, .NET Core 3.1 and WPF).
Simply close Visual Studio and restart it: 98% of the times error disappears (will reappear sometime in the future).
You have an invalid Style. It may compile, as the XAML is syntactically correct, but the semantics of the markup are wrong. Since you are referencing the Style using DynamicResource the error occurs at runtime. But I wonder why don't get a XAML Designer error.
You are setting the ComboBox.Template property twice. Moreover and most important, the first ControlTemplate at the top of the Style is targeting the wrong type TextBox:
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Border CornerRadius="25"
BorderThickness="1,1,2,2">
</Border>
</Grid>
</ControlTemplate>
The type must be of course <ControlTemplate TargetType="ComboBox">.
Since you are referencing a ControlTemplate resource later
<Setter Property="Template" Value="{StaticResource ComboBoxTemplate}" />
I think you want to remove the first ControlTemplate. If you want to change the appearance of the TextBox, you would need to override the complete ControlTemplate of the ComboBox.
You may should run Clean Solution and Rebuild Solution.
I am trying to use a ResourceDictionary and a Style in my WPF program. When I only have ResourceDictionary in <Window.Resources> everything works fine but as soon as I add a <Style> the program displays "Resource not found" for the Dictionary and I get an error "The resource "PlusMinusExpander" could not be resolved."
<Window.Resources>
<Style x:Key="CurrencyCellStyle" TargetType="{x:Type DataGridCell}">
<Setter Property="Foreground" Value="#dddddd" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
</Trigger>
</Style.Triggers>
</Style>
<ResourceDictionary x:Key="hello" Source="Assets/PlusMinusExpanderStyles.xaml" />
</Window.Resources>
<Expander Header="Plus Minus Expander" Style="{StaticResource PlusMinusExpander}" HorizontalAlignment="Right" Width="292">
<Grid Background="Transparent">
<TextBlock>Item1</TextBlock>
</Grid>
</Expander>
I want to be able to do Style="{StaticResource PlusMinusExpander}" even after adding the CurrencyCellStyle Style.
I have seen similar questions online but none of their solutions have worked for me yet. Is there a way to use both the Style and the ResourceDictionary?
The type of Window.Resources property is ResourceDictionary, so cannot put two different types of XAML element as brothers. Instead, you should:
Put a separated ResourceDictionary into the Window.Resources property and write the Style inside the ResourceDictionary.
Remove the x:Key property from the ResourceDictionary.
<FrameworkElement.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Assets/PlusMinusExpanderStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style x:Key="CurrencyCellStyle" TargetType="{x:Type DataGridCell}">
<Setter Property="Foreground" Value="#dddddd" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</FrameworkElement.Resources>
I have some buttons -in different windows- that have the same content. But if two windows surfaced together,out of the first window's button content disappears.
Buttons Style is :
<Style TargetType="{x:Type Button}" x:Key="BSaveBtn">
<Setter Property="Padding" Value="5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Width" Value="70"/>
<Setter Property="Height" Value="68"/>
<Setter Property="Background" Value="{DynamicResource FlatGreen}"/>
<Setter Property="Template" Value="{DynamicResource FlatGreenBtnHover}"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Vertical" FlowDirection="RightToLeft">
<Image Width="30" Source="/login;component/img/buttonpic/save.png"/>
<TextBlock Text="save" FontSize="16" FontFamily="/login;component/fonts/#Droid Arabic Kufi" Foreground="White" HorizontalAlignment="Center"/>
</StackPanel>
</Setter.Value>
</Setter>
</Style>
button Code in windows is :
<Button Style="{DynamicResource BSaveBtn}" Template="{DynamicResource FlatGreenBtnHover}" />
problems occurs only with content -not another style properties- .
Seems to work fine for me when I tested it here.
A few things I noticed though that may help. You don't need them to be DynamicResource, they should really be StaticResource unless you plan on modifying them.
I assume you are declaring these in the Windows.Resource section or repeating them on each window?
If so you should centralize those to a ResourceDictionary.
Create a new Resource Dictionary put your style in there like so:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type Button}" x:Key="BSaveBtn">
<Setter Property="Padding" Value="5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Width" Value="70"/>
<Setter Property="Height" Value="68"/>
<Setter Property="Background" Value="{DynamicResource FlatGreen}"/>
<Setter Property="Template" Value="{DynamicResource FlatGreenBtnHover}"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Vertical" FlowDirection="RightToLeft">
<Image Width="30" Source="/login;component/img/buttonpic/save.png"/>
<TextBlock Text="save" FontSize="16" FontFamily="/login;component/fonts/#Droid Arabic Kufi" Foreground="White" HorizontalAlignment="Center"/>
</StackPanel>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Then in your App.xaml put the following:
<ResourceDictionary>
<ResourceDictionary Source="MyResources.xaml" />
</ResourceDictionary>
The Image should really be in a dictionary to avoid loading it multiple times. Just add a line in that ResourceDictionary like so:
<BitmapImage UriSource="/login;component/Images/Save.png" x:Key="Save" PresentationOptions:Freeze="True" />
Setting the PresentationOptions:Freeze will also help if the image is never being modified.
Your call to the image would then change to be:
<StackPanel Orientation="Vertical" FlowDirection="RightToLeft">
<Image Width="30" Source="{StaticResource Save}"/>
<TextBlock Text="save" FontSize="16" FontFamily="/login;component/fonts/#Droid Arabic Kufi" Foreground="White" HorizontalAlignment="Center"/>
</StackPanel>
Once your resources are centralized in a ResourceDictionary (or multiple) it makes it easy to apply those same styles anywhere in your application and hopefully will help with your issue. If not please give more info on the problem you have such as sample code to make the issue happen please.
An instance of an element can only appear once in the visual tree. You can set the x:Shared attribute of the Style to False in order for a new instance of the StackPanel to get created for each Button to which you apply the style:
<Style TargetType="{x:Type Button}" x:Key="BSaveBtn" x:Shared="False">
<Setter Property="Padding" Value="5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Width" Value="70"/>
<Setter Property="Height" Value="68"/>
<Setter Property="Background" Value="{DynamicResource FlatGreen}"/>
<Setter Property="Template" Value="{DynamicResource FlatGreenBtnHover}"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Vertical" FlowDirection="RightToLeft">
<Image Width="30" Source="/login;component/img/buttonpic/save.png"/>
<TextBlock Text="save" FontSize="16" FontFamily="/login;component/fonts/#Droid Arabic Kufi" Foreground="White" HorizontalAlignment="Center"/>
</StackPanel>
</Setter.Value>
</Setter>
</Style>
I have a style which works well
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:Downloader.App.ResourceDictionaries.NamedStyles">
<Style x:Key="TextBoxWithDefaultTextStyle" TargetType="TextBox">
<!--Padding for typed text-->
<Setter Property="Padding" Value="5, 2, 5, 0"/>
<Setter Property="Background" Value="White" />
<Setter Property="BorderBrush" Value="#FF858585" />
<Setter Property="BorderThickness" Value="3" />
<Setter Property="Border.CornerRadius" Value="10" />
<Setter Property="Control.Template" Value="{StaticResource TextBoxBaseControlTemplate}"></Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel>
<Border BorderBrush="Brown" BorderThickness="5"
CornerRadius="2">
<AdornedElementPlaceholder x:Name="controlWithError"/>
</Border>
<TextBlock Foreground="Red" FontSize="20" FontFamily="Segoe UI" Margin="3,0,0,0">!</TextBlock>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
Then I want to put it into separate resource as I do with ordinary template
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:Downloader.App.ResourceDictionaries.NamedStyles">
<Style x:Key="TextBoxWithDefaultTextStyle" TargetType="TextBox">
<!--Padding for typed text-->
<Setter Property="Padding" Value="5, 2, 5, 0"/>
<Setter Property="Background" Value="White" />
<Setter Property="BorderBrush" Value="#FF858585" />
<Setter Property="BorderThickness" Value="3" />
<Setter Property="Border.CornerRadius" Value="10" />
<Setter Property="Control.Template" Value="{StaticResource TextBoxBaseControlTemplate}"></Setter>
<Setter Property="Validation.ErrorTemplate" Value="{StaticResource TextBoxValidationTemplate}"></Setter>
</Style>
</ResourceDictionary>
TextBoxValidationTemplate.xaml:
<AdornedElementPlaceholder x:Name="controlWithError"/>
</Border>
<TextBlock Foreground="Red" FontSize="20" FontFamily="Segoe UI" Margin="3,0,0,0">!</TextBlock>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Then I run the application and type invalid data and get the exception:
'{DependencyProperty.UnsetValue}' is not a valid value for property 'ErrorTemplate'.
If I apply the error template directly
<TextBox Text="{Binding UserName, Mode=TwoWay, ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}"
Validation.ErrorTemplate="{StaticResource TextBoxValidationTemplate}"
Style="{StaticResource TextBoxWithDefaultTextStyle}"
Grid.Row="2"
Grid.Column="0"
Margin="5,2,5,2"
Grid.ColumnSpan="2"/>
it works as well so the file is OK
Found it my self. Templates must go first, then styles
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" xmlns:vm="clr-namespace:Downloader.App.ViewModel" />
</ResourceDictionary>
<ResourceDictionary Source="ResourceDictionaries\Templates\TextBoxBaseControlTemplate.xaml" />
<ResourceDictionary Source="ResourceDictionaries\Templates\TextBoxValidationTemplate.xaml" />
<ResourceDictionary Source="ResourceDictionaries\Templates\PasswordBoxControlTemplate.xaml" />
<ResourceDictionary Source="ResourceDictionaries\NamedStyles\TextBoxWithDefaultTextStyle.xaml" />
<ResourceDictionary Source="ResourceDictionaries\NamedStyles\PasswordBoxStyle.xaml" />
<ResourceDictionary Source="ResourceDictionaries\Images\Common.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
So I have an application with a style put directly into the App.xaml file as such:
<Application x:Class="Test.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="OnStartup">
<Application.Resources>
<Style x:Key="SpecialButtonStyle" TargetType="Button">
<Setter Property="Content" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" />
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Block.Foreground" Value="White" />
<Setter Property="TextBlock.Foreground" Value="White" />
<Setter Property="TextElement.Foreground" Value="White" />
<Setter Property="FontWeight" Value="Bold" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" Padding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BorderThickness}">
<Border Background="{TemplateBinding BorderBrush}">
<ContentControl Foreground="White">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</ContentControl>
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Application.Resources>
</Application>
I want to include this as a style in my class Library, so that any xaml projects that reference that library can see "SpecialButtonStyle" as a selectable "Style" in the designer.
I've read several articles about ResourceDictionaries and creating portable XAML controls, but I'm still confused. I basically want a collection of styles included as part of a class library.
(I can only post 2 links until I get a higher StackOverflow reputation)
http://timheuer.com/blog/archive/2012/03/07/creating-custom-controls-for-metro-style-apps.aspx
http://visualstudiomagazine.com/articles/2015/03/01/everyone-gets-xaml-with-xamarinforms.aspx
Any help would be greatly appreciated. Thanks!
What you read is correct.
What you need is to create a plain ResourceDictionary inside your shared assembly with a given name.
In your App.xaml you then can include this ResourceDictionary as a MergedDictionary and therefore your whole app will have access to all of the shared dictionaries resources.
Steps:
Create another project WPF Control Library Project (doesn't matter about User or Custom)
In the new project right click -> Add -> ResourceDictionary
Paste your style in so it looks like the following:
Dictionary1.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="SpecialButtonStyle" TargetType="Button">
<Setter Property="Content" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" />
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Block.Foreground" Value="White" />
<Setter Property="TextBlock.Foreground" Value="White" />
<Setter Property="TextElement.Foreground" Value="White" />
<Setter Property="FontWeight" Value="Bold" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" Padding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BorderThickness}">
<Border Background="{TemplateBinding BorderBrush}">
<ContentControl Foreground="White">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</ContentControl>
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
In your main project reference this new Control Library
In App.xaml reference Dictionary1.xaml
App.xaml
<Application x:Class="WpfApplication1.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="NestedXamlObjects.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/WpfControlLibrary1;component/Dictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Just came across this post. If you are using Xamarin.Forms or .NET MAUI, you also can do it this way.
I manage all my styles in a shared class library project (same as step 1-4 from the accepted answer) and
add the ResourceDictionary as shown below.
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:KlipperRemoteControl"
xmlns:shared="clr-namespace:AndreasReitberger.Shared;assembly=SharedMauiXamlStylesLibrary"
x:Class="KlipperRemoteControl.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<shared:DefaultTheme />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
DefaultTheme.xaml form the library.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AndreasReitberger.Shared.DefaultTheme"
xmlns:ios="clr-namespace:Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;assembly=Microsoft.Maui.Controls"
>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Themes/Controls/BoxView.xaml" />
<ResourceDictionary Source="/Themes/Controls/Editor.xaml" />
<ResourceDictionary Source="/Themes/Controls/Entry.xaml" />
<ResourceDictionary Source="/Themes/Controls/Label.xaml" />
<ResourceDictionary Source="/Themes/Controls/Grid.xaml" />
<ResourceDictionary Source="/Themes/Controls/Frame.xaml" />
</ResourceDictionary.MergedDictionaries>
<Color x:Key="Transparent">Transparent</Color>
<Color x:Key="TappedBackgroundColor">#eaeaea</Color>
<Color x:Key="Green">#33AD79</Color>
<Color x:Key="LightGreen">#38ef7d</Color>
<Color x:Key="DarkGreen">#11998e</Color>
<Color x:Key="Red">#ff4a4a</Color>
<Color x:Key="DarkRed">#93291e</Color>
<Color x:Key="Orange">#F78836</Color>
<Color x:Key="DarkOrange">#F83017</Color>
<Color x:Key="Blue">#3C8CF1</Color>
<Color x:Key="LightBlue">#6dd5ed</Color>
<Color x:Key="DarkBlue">#2193b0</Color>
<Color x:Key="HyperLink">#567cd7</Color>
<Color x:Key="White">#ffffff</Color>
<Color x:Key="Black">#000000</Color>
<Color x:Key="primary-lighter">#edcacd</Color>
<Color x:Key="Liliac">#d483fc</Color>
<Color x:Key="Purpleish-Blue">#5d4cf7</Color>
<Color x:Key="Link">#567cd7</Color>
<Color x:Key="Bright-Cyan">#3cdeff</Color>
<Color x:Key="Lemon-Lime">#bdff27</Color>
<Color x:Key="Yellow">#E9B31A</Color>
<Color x:Key="Pink">#C6275C</Color>
</ResourceDictionary>