Using BasedOn property with a Style defined in a different dictionary - c#

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>

Related

WPF - Styles declared in Resource Dictionary not getting applied

I have added the following styles in App.xml file of WPF application under Application.Resources tag and these styles are getting applied to the controls.
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="16" />
<Setter Property="FontFamily" Value="Calibri" />
</Style>
<Style TargetType="{x:Type Control}" x:Key="fontStyling">
<Setter Property="FontSize" Value="16" />
<Setter Property="FontFamily" Value="Calibri" />
</Style>
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource fontStyling}" />
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource fontStyling}" />
Now, i have created a "Resource Dictionary" file, moved the above styles to Resource dictionary file and accessed the "Resource Dictionary" file in the App.XAML file using merged dictionaries
<ResourceDictionary x:Key="GlobalSettingsDictionary">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ResourceDictionaries/GlobalSettings.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
When i run the WPF application then the Styles in the resource dictionary are not getting applied to the controls present in the Main Window. When i use the same styles in App.xaml file then they are getting applied
Am i missing anything? Can you please suggest on what needs to be done to get the styles defined in the Resource dictionary are applied to the controls in the MainWindow.xaml?

DynamicResource wont change color

First of all I created two themes inside resources directory
Then I added light theme and changed some dynamic resources to SecondaryColor which is black
<?xml version = "1.0" encoding = "UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Eden"
x:Class="Eden.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary Source="Resources/Themes/LightTheme.xaml"/>
<Style TargetType="Label">
<Setter Property="TextColor" Value="{DynamicResource SecondaryColor}" />
<Setter Property="FontFamily" Value="OpenSansRegular" />
</Style>
<Style TargetType="Button">
<Setter Property="TextColor" Value="{DynamicResource SecondaryColor}" />
<Setter Property="FontFamily" Value="OpenSansRegular" />
<Setter Property="BackgroundColor" Value="{DynamicResource SecondaryColor}" />
<Setter Property="Padding" Value="14,10" />
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>
Light Theme
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Eden.Resources.Themes.LightTheme">
<Color x:Key="PageBackgroundColor">White</Color>
<Color x:Key="NavigationBarColor">WhiteSmoke</Color>
<Color x:Key="PrimaryColor">WhiteSmoke</Color>
<Color x:Key="SecondaryColor">Black</Color>
<Color x:Key="PrimaryTextColor">Black</Color>
<Color x:Key="SecondaryTextColor">White</Color>
<Color x:Key="TertiaryTextColor">Gray</Color>
<Color x:Key="TransparentColor">Transparent</Color>
</ResourceDictionary>
But when I open app button background is white.
What I am doing wrong?
I made a test app and it works here.
This is different ,there are xaml.cs files
Added a DarkTheme.xaml ( ContentPage )
And change it to ResourceDictionary
This is how it looks in your example code
LightTheme.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp1.LightTheme">
<Color x:Key="PageBackgroundColor">White</Color>
<Color x:Key="NavigationBarColor">WhiteSmoke</Color>
<Color x:Key="PrimaryColor">WhiteSmoke</Color>
<Color x:Key="SecondaryColor">Black</Color>
<Color x:Key="PrimaryTextColor">Black</Color>
<Color x:Key="SecondaryTextColor">White</Color>
<Color x:Key="TertiaryTextColor">Gray</Color>
<Color x:Key="TransparentColor">Transparent</Color>
App.xaml.cs
<Application.Resources>
<ResourceDictionary>
<!--If you want to use LightTheme and DarkTheme add both-->
<ResourceDictionary Source="Resources/Themes/LightTheme.xaml"/>
<ResourceDictionary Source="Resources/Themes/DarkTheme.xaml"/>
<Style TargetType="Label">
<Setter Property="TextColor" Value="{DynamicResource SecondaryColor}" />
<Setter Property="FontFamily" Value="OpenSansRegular" />
</Style>
<Style TargetType="Button">
<Setter Property="TextColor" Value="{DynamicResource SecondaryColor}" />
<Setter Property="FontFamily" Value="OpenSansRegular" />
<Setter Property="BackgroundColor" Value="{DynamicResource SecondaryColor}" />
<Setter Property="Padding" Value="14,10" />
</Style>
</ResourceDictionary>
</Application.Resources>
Your example code is here https://github.com/borisoprit/MauiApp1

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.

WPF style from HDD file

In my application I'm using ResourceDictionaries for styles. Example:
<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="SimpleButton">
<Setter Property="Foreground" Value="{DynamicResource SpecialRed}"/>
<Setter Property="FontSize" Value="40"/>
<Setter Property="Margin" Value="10"/>
</Style>
</ResourceDictionary>
Lets say that as a user I know how resource dictionary look like. Is it possible to overwrite the resource from my own file from HDD? I want to add the functionality which allows user to do this.
My HDD file:
<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="SimpleButton">
<Setter Property="Foreground" Value="{DynamicResource SpecialRed}"/>
<Setter Property="FontSize" Value="70"/>
<Setter Property="Margin" Value="20"/>
</Style>
</ResourceDictionary>
If you insist on doing that (I wouldn't), you can merge resource dictionaries at runtime: Dynamically loading resource dictionary files to a wpf application gives an error

Replace default WPF theme Style for all controls

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

Categories