Replace default WPF theme Style for all controls - c#

I tried to replace the default style at my WPF project for all my controls.
I created a ResourceDictionary like this:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Black"/>
</Style>
</ResourceDictionary>
and in my App.Xaml I wrote this:
<Application.Resources>
<ResourceDictionary >
<ResourceDictionary.MergedDictionaries >
<ResourceDictionary Source="pack://application:,,,/MYTestTheme;component/Themes/Aero.NormalColor.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Now in my MainWindow.Xaml I created a button and the style was on it.
I want to crate a new button MyButton who inherited from button
And I want every Button defined style will be on MyButton when I place it on my MainWindow.Xaml but that does not happen.
One more important thing I don't want to use BasedOn.
I was see this code at some blogas:
<Application>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source=”{ThemeDictionary MyApplication}”/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
But it's not worked!!!
Thanks

Give your key a string name:
<Style x:Key="MyButton" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Black"/>
</Style>
And add this in the App.XAML (outside your Application.Resources block):
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource MyButton}" />

Related

How can I use StaticResources defined in App.xaml in other ResourceDictionaries?

I defined some StaticResource styles inside App.xaml to use it across the app:
<Application x:Class="TaskListApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TaskListApp"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<SolidColorBrush x:Key="primaryColor" Color="#B5B4D9"/>
<SolidColorBrush x:Key="secondaryColor" Color="#393E59"/>
<SolidColorBrush x:Key="backgroundColor" Color="#2a2e42"/>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="./Themes/CheckboxTheme.xaml"/>
<ResourceDictionary Source="./Themes/TasksTheme.xaml"/>
<ResourceDictionary Source="./Themes/TaskListTheme.xaml"/>
<ResourceDictionary Source="./Themes/MenuButtonTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Using it in MainWindow.xaml is making no errors and works just fine:
<Grid Grid.Row="2"
Background="{StaticResource backgroundColor}"
</Grid>
But when I added it inside a ResourceDictionary (in this case TaskListTheme.xaml), I got an exception:
Exception: Cannot find resource named 'primaryColor'. Resource names are case
sensitive.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="ListBoxItem" x:Key="TaskListTheme">
<Setter Property="Margin" Value="0,0,0,5"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Label Grid.Column="1" Content="{Binding TaskListItemName}"
Margin="0"
Height="50"
Background="{StaticResource primaryColor}"
Padding="10,0,0,0"
Foreground="{StaticResource secondaryColor}"
FontSize="15"
FontWeight="SemiBold"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center"
BorderThickness="0"/>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
How can I resolve this kind of problem?
If a resource in TaskListTheme.xaml has a dependency on a resource that is defined in another resource dictionary, you should merge the latter into TaskListTheme.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Colors.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
So move your *Color brush resources to Colors.xaml and then either merge Colors.xaml into the other resource dictionaries or into App.xaml:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Colors.xaml"/>
<ResourceDictionary Source="./Themes/CheckboxTheme.xaml"/>
<ResourceDictionary Source="./Themes/TasksTheme.xaml"/>
<ResourceDictionary Source="./Themes/TaskListTheme.xaml"/>
<ResourceDictionary Source="./Themes/MenuButtonTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
I think mm8's answer is standard way. Said that, you can just move resources directly under Application.Resources to ResourceDictionary inside MergedDictionaries to achieve the same effect.
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<SolidColorBrush x:Key="primaryColor" Color="#B5B4D9"/>
<SolidColorBrush x:Key="secondaryColor" Color="#393E59"/>
<SolidColorBrush x:Key="backgroundColor" Color="#2a2e42"/>
</ResourceDictionary>
<ResourceDictionary Source="./Themes/CheckboxTheme.xaml"/>
<ResourceDictionary Source="./Themes/TasksTheme.xaml"/>
<ResourceDictionary Source="./Themes/TaskListTheme.xaml"/>
<ResourceDictionary Source="./Themes/MenuButtonTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>

XAML resouce dictionary - unable to apply default style

I'm currently facing a really odd situation.
I have a WPF application with the following lines inside App.xaml:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<local:AppBootstrapper x:Key="bootstrapper" />
</ResourceDictionary>
<ResourceDictionary Source="./Styles/MyTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Then I have some dictionaries in MyTheme.xaml:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="./UserControlStyles.xaml"/>
<ResourceDictionary Source="./WizardStyle.xaml"/>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Dark.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.Blue.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Blue.xaml" />
<ResourceDictionary Source="./DataGridStyles.xaml"/>
<ResourceDictionary Source="./TreeViewStyles.xaml"/>
<ResourceDictionary Source="./ToggleButtonStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
Finally there is a DataGrid that I want to apply to all DataGrids of my application by default (in DataGridStyles.xaml):
<ResourceDictionary>
<Style TargetType="{x:Type DataGrid}" BasedOn="{StaticResource MaterialDesignDataGrid}">
<Setter Property="AutoGenerateColumns" Value="False" />
<Setter Property="CanUserAddRows" Value="False" />
<Setter Property="CanUserDeleteRows" Value="False" />
<Setter Property="SelectionMode" Value="Single" />
</Style>
</ResourceDictionary>
The DataGrid style is not applying for some reason, but it works if I put it directly inside MyTheme.xaml:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="./UserControlStyles.xaml"/>
<ResourceDictionary Source="./WizardStyle.xaml"/>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Dark.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.Blue.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Blue.xaml" />
<ResourceDictionary Source="./DataGridStyles.xaml"/>
<ResourceDictionary Source="./TreeViewStyles.xaml"/>
<ResourceDictionary Source="./ToggleButtonStyles.xaml"/>
<ResourceDictionary>
<Style TargetType="{x:Type DataGrid}" BasedOn="{StaticResource MaterialDesignDataGrid}">
<Setter Property="AutoGenerateColumns" Value="False" />
<Setter Property="CanUserAddRows" Value="False" />
<Setter Property="CanUserDeleteRows" Value="False" />
<Setter Property="SelectionMode" Value="Single" />
</Style>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
Note that MaterialDesignDataGrid is defined inside MaterialDesignTheme.Defaults.xaml.
Is it an expected behavior? Am I doing something wrong?
Thank you very much for your time.
Try different settings for the build action of your DataGridStyles.xaml. I think it should work if you set it to Page.

Use resources to set foreground colour of a textbox

I have a resource file that contains the colours that I want to use in my project. I've successfully used these resources to set the style of my WPF windows and controls. What I;m struggling to achieve is to use these same resources to programatically change the foreground colour of a textbox. I'm using C# and WPF.
This is my resource file and it's stored in a /Resources/Colours.xaml file.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!--Application Colour pallette-->
<SolidColorBrush x:Key="DefaultColour" Color="#FF193B60"></SolidColorBrush>
<SolidColorBrush x:Key="BaseColour" Color="#FF2E5076"></SolidColorBrush>
<SolidColorBrush x:Key="HighlightColour" Color="#FF506F93"></SolidColorBrush>
<SolidColorBrush x:Key="ForegroundColour" Color="#FFB7D7F9 "></SolidColorBrush>
<SolidColorBrush x:Key="AlternateColour" Color="#FFB7D7F9"></SolidColorBrush>
<SolidColorBrush x:Key="HeaderColour" Color="#FF02162B"></SolidColorBrush>
<Color x:Key="Media.DefaultColour">#FF193B60</Color>
<Color x:Key="Media.BaseColour">#FF2E5076</Color>
<Color x:Key="Media.HighlightColour">#FF506F93</Color>
<Color x:Key="Media.ForegroundColour">#FFB7D7F9</Color>
<Color x:Key="Media.AlternateColour">#FFB7D7F9</Color>
<Color x:Key="Media.HeaderColour">#FF02162B</Color>
I've merged the resourcedictionary in the App.xaml file
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://Application:,,,/Resources/Colours.xaml" />
</Application.Resources>
Can anyone offer guidance for me please?
Thanks in advance.
After comments
Use Style.Trigger for your Textbox:
<TextBox ...>
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="{...focusedcolor...}" />
<Style.Triggers>
<Trigger Property="IsFocused" Value="False">
<Setter Property="Foreground" Value="{...unfocused...}" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>

wpf resource dictionary does not exist in namespace?

I'm using .net 4.5.2
I do not have a clue why my project continues to say the resource is missing. I've paced my mainWindow.xaml inside a folder and repathed the app to target its location. What is really odd is the fact that it displays correctly in visual studio but when i try to compile it errors out saying the 'themes' namespace does not exist in the project.
Severity Code Description Project File Line Error CS0234 The type or
namespace name 'Themes' does not exist in the namespace
'WpfApplication1' (are you missing an assembly
reference?) WpfApplication1 C:\Users\jmartini\Projects\wpf_Styling_4.5.2\WpfApplication1\WpfApplication1\obj\Debug\View\MainWindow.g.i.cs 33
Here is my code...
MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
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:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="200" Width="250"
WindowStartupLocation="CenterScreen">
<DockPanel>
<Button Content="Push It!" Width="70" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</DockPanel>
</Window>
JMStyles.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1.Themes">
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontSize" Value="15" />
<Setter Property="SnapsToDevicePixels" Value="True" />
</Style>
</ResourceDictionary>
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"
xmlns:local="clr-namespace:WpfApplication1"
StartupUri="View/MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes/JMStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Solution to get it working...
I removed this line from the style page:
xmlns:local="clr-namespace:WpfApplication1.Themes"
original
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontSize" Value="15" />
<Setter Property="SnapsToDevicePixels" Value="True" />
</Style>
</ResourceDictionary>
I removed this line of code
xmlns:local="clr-namespace:WpfApplication1.Themes"
from the style page file contents below...
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1.Themes">
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontSize" Value="15" />
<Setter Property="SnapsToDevicePixels" Value="True" />
</Style>
</ResourceDictionary>
Microsoft.Windows.Themes is found in the theme-specific PresentationFramework assemblies. You'll need to add a reference to one of the following depending on which one is referenced in your XAML:
PresentationFramework.Aero.dll
PresentationFramework.AeroLite.dll
PresentationFramework.Classic.dll
PresentationFramework.Luna.dll
PresentationFramework.Royale.dll
For some reason Visual Studio doesn't recognize namespaces of folders with only Resource Dictionary files. If you add another file in that folder like a User Control you would notice that the namespace would be recognized. The solution is to remove the line of
"local" namespace:
xmlns:local="clr-namespace:WpfApplication1.Themes
because we will mention the resourse with
<ResourceDictionary Source="Themes/...
Without needing the namespace, in difference when we create User Controls that we do need the namespace in the code of the file where they're used

Using BasedOn property with a Style defined in a different dictionary

The application I'm working on has 2 ResourceDictionary, DefaultStyles.xaml and CustomStyles.xaml.
Is it possible that a style in the CustomStyles dictionary uses a base style defined in the other dictionary?
DefaultStyles.xaml:
<Style x:Key="TextBlockDefaultStyle" TargetType="TextBlock">
<Setter Property="Margin" Value="4" />
</Style>
CustomStyles.xaml:
<Style x:Key="SectionTitleStyle" TargetType="TextBlock" BasedOn="{StaticResource TextBlockDefaultStyle}">
<Setter Property="FontSize" Value="16" />
</Style>
App.xaml:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Assets/Styles/DefaultStyles.xaml"/>
<ResourceDictionary Source="Assets/Styles/CustomStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
When the code runs, the following exception is thrown:
Cannot find a Resource with the Name/Key TextBlockDefaultStyle.
It works well if both styles are in the same file.
You need to reference the dictionary with the other style directly.
CustomStyles.xaml:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="DefaultStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style x:Key="SectionTitleStyle" TargetType="TextBlock" BasedOn="{StaticResource TextBlockDefaultStyle}">
<Setter Property="FontSize" Value="16" />
</Style>

Categories