Finding resources in wpf with several levels - c#

I have a problem when I have several levels or resources in wpf
for instance if i have this code
main.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Style TargetType="{x:Type TextBox}" x:Key="Main">
<Setter Property="FontSize" Value="50"/>
</Style>
</ResourceDictionary>
sub.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Style TargetType="{x:Type TextBox}" x:Key="Sub" BasedOn="{StaticResource Main}">
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="20"/>
</Style>
</ResourceDictionary>
all.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:p19"
>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Main.xaml"/>
<ResourceDictionary Source="Sub.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
app.xaml
<Application.Resources>
<ResourceDictionary Source="All.xaml"/>
</Application.Resources>
in mainwindow i just have
<Grid>
<TextBox Style="{StaticResource Sub}"/>
</Grid>
This won't work.
However if I put resources directly into app.xaml (and not through all.xaml) like this
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Main.xaml"/>
<ResourceDictionary Source="Sub.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
It does work. I think i remember that someone said somewhere (I can't remember where) that this is a bug in wpf and can be solved with some empty styles and with new .net framework.
I tried 2015 rc and 4.6 and it still doesn't work.
Does someone know how to fix it and where? And can they try out the code on their side to see if it works?
Thanks in advance for your help

The trick is to put this dictionary in turn into a merged dictionary:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="All.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Should work fine then.
Edit
However you get into trouble when you try to access a style from another dictionary. To get rid of this reference it in the sub.xaml too:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Main.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type TextBox}" x:Key="Sub" BasedOn="{StaticResource Main}">
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="20"/>
</Style>
</ResourceDictionary>

Related

How to override ComboBox ToggleButton from Material Design for XAML?

I'm new in WPF.
I have an issue with overriding MaterialDesignComboBoxToggleButton
style. I wanna to replace "Template" setter with own, but my content from control template always ignores. Why this occurred? With other styles i haven't this problem.
Bellow code demonstrates what i need.
Overriedes.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ComboBox.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style BasedOn="{StaticResource MaterialDesignComboBoxToggleButton}" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<TextBlock FontSize="50" FontWeight="Bold">$$</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
App.xaml
<Application x:Class="Wpf.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-Wpf" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
StartupUri="Views/MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<materialDesign:CustomColorTheme BaseTheme="Light" PrimaryColor="#FFD8E1FF" SecondaryColor="#FFD8E1FF" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source="/Overrides.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Add the same resource key to your custom style like this:
<Style
x:Key="MaterialDesignComboBoxToggleButton"
BasedOn="{StaticResource MaterialDesignComboBoxToggleButton}"
TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<TextBlock FontSize="50" FontWeight="Bold">$$</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and you don't need to add resources like this in Overrides.xaml file:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ComboBox.xaml" />
</ResourceDictionary.MergedDictionaries>
because the MDIX resources already included by MaterialDesignTheme.Defaults.xaml that you added in App.xaml file.
In my case override style in window not working ,but when I tried in App.xml then it works. I changed the style for toggle button by another style . the code is :
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes/IG/IG.MSControls.Core.Implicit.xaml" />
<ResourceDictionary Source="Themes/IG/IG.MSControls.Toolkit.Implicit.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.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.Indigo.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border CornerRadius="8" BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="#FF0F0F4B" />
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Background" Value="#FF73ADDE" />
<Setter Property="Foreground" Value="#FF150404" />
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</Application.Resources>

WPF dynamic resource not found in MergedDictionary but outside it is fine

I have a main Class (with an MainView.xaml) that dynamically loads various other Pages long after the MainView has been shown.
So MainView.xaml has following style defined:
<Window.Resources>
<Style x:Key="ErrorTemplate" TargetType="TextBox">
<Setter Property="FontSize" Value="30"/>
</Style>
</Window.Resources>
In one of the loaded pages I had following declaration:
<Page.Resources>
<Style x:Key="ErrorStyle" TargetType="TextBox">
<Setter Property="Validation.ErrorTemplate" Value="{DynamicResource ErrorTemplate"/>
</Style>
</Page.Resources>
This worked fine.
Now I needed to load other resources from an external XAML file so I used MergedDictionaries.
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- Guaranteed to not have an ErrorTemplate key -->
<ResourceDictionary Source="MoreStyles.xaml"/>
<ResourceDictionary>
<Style x:Key="ErrorStyle" TargetType="TextBox">
<Setter Property="Validation.ErrorTemplate" Value="{DynamicResource ErrorTemplate"/>
</Style>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Page.Resources>
And now I started to receive the message that ErrorTemplate could not be resolved.
Moving it outside of the MergedDictionary fixed the problem again.
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MoreStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="ErrorStyle" TargetType="TextBox">
<Setter Property="Validation.ErrorTemplate" Value="{DynamicResource ErrorTemplate"/>
</Style>
</ResourceDictionary>
</Page.Resources>
What is happening here?

MahApps Resource Dictionary error

So, today I installed MahApps in my WPF project. All went smoothly until I wanted to use the build-in styles.
This is my 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="MainWindow.xaml">
<Application.Resources>
<BitmapImage x:Key="logoImage" UriSource="Images/Logo.png" />
<BitmapImage x:Key="profileButtonImage" UriSource="Images/ProfileButton.png" />
<BitmapImage x:Key="settingsButtonImage" UriSource="Images/SettingsButton.png" />
<BitmapImage x:Key="profileIconImage" UriSource="Images/profileIcon.png" />
<BitmapImage x:Key="listenIconImage" UriSource="Images/listenIcon.png" />
<BitmapImage x:Key="statsIconImage" UriSource="Images/statsIcon.png" />
<BitmapImage x:Key="accountButtonImage" UriSource="Images/accountButton.png" />
<BitmapImage x:Key="pauseButtomImage" UriSource="Images/pause-button.png" />
<BitmapImage x:Key="playButtomImage" UriSource="Images/play-button.png" />
<BitmapImage x:Key="stopButtomImage" UriSource="Images/stop-button.png" />
<BitmapImage x:Key="doneButtonImage" UriSource="Images/doneButton.png" />
<BitmapImage x:Key="arrowButtonImage" UriSource="Images/arrow.png" />
<BitmapImage x:Key="doneButtonHoverImage" UriSource="Images/doneButtonHover.png" />
<FontFamily x:Key="Novo">/Fonts/#Novecentosanswide-Medium</FontFamily>
<Style x:Key="ButtonStyle">
<Setter Property="Border.Background" Value="#262a33" />
<Style.Triggers>
<Trigger Property="Border.IsMouseOver" Value="True">
<Setter Property="Border.Background" Value="#1d2027" />
</Trigger>
</Style.Triggers>
</Style>
<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.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
The BitmapImages are there for some of my buttons. My issue is that when I try to compile I get the following error:
All objects added to an IDictionary must have a Key attribute or some other type of key associated with them.
Each dictionary entry must have an associated key.
I installed all 3 of the MahApps NuGets, do you have any idea why these errors appear?
Wrap all the resources inside another ResourceDictionary and in that one add MahApp resources as MergedDictionaries
Thank's Ruben, work for me only wrap all resources inside ResourceDictionary
<Application.Resources>
<ResourceDictionary>
<!--Estilo Validação-->
<Style TargetType="TextBox">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<StackPanel>
<AdornedElementPlaceholder x:Name="placeholder"/>
<TextBlock FontSize="12" Foreground="Red"
Text="{Binding ElementName=placeholder,Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
<!--FIM Estilo Validação-->
<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.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>

Cannot find a Resource with the Name/Key NavigationPaneButton

I am trying to reference the NavigationPaneButton resource in my styles.xaml. I've defined them all in different resource files and linked them all properly in the app.xaml with the right order. But I still get the exception
"Cannot find a Resource with the Name/Key NavigationPaneButton"
Is there something I am missing?
<ResourceDictionary
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"
mc:Ignorable="d">
<Style TargetType="Button" x:Key="WasHamburguerButton">
<Setter Property="Background" Value="{ThemeResource NavigationPaneButton}" />
<Setter Property="Foreground" Value="{ThemeResource NavigationPaneText}"/>
</Style>
</ResourceDictionary>
I've defined the resource in AppTheme.xaml
<ResourceDictionary
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"
mc:Ignorable="d">
<SolidColorBrush x:Key="NavigationPaneText" Color="{ThemeResource NavigationPaneTextColor}"/>
<SolidColorBrush x:Key="NavigationPaneButton" Color="{ThemeResource NavigationPaneButtonColor}"/>
</ResourceDictionary>
And the color in AppColor.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
<Color x:Key="NavigationPaneTextColor">#ffffff</Color>
<Color x:Key="NavigationPaneButtonColor">#D13438</Color>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
This is my app.xaml
<Application
x:Class="WindowsUniversalApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WindowsUniversalApp">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/AppColors.xaml"/>
<ResourceDictionary Source="Resources/AppTheme.xaml"/>
<ResourceDictionary Source="Resources/Styles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
It will work if you link them like this:
Styles -> AppTheme -> AppColors
So, AppTheme knows about AppColors:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestImage.Resources">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ms-appx:///Resources/AppColors.xaml"/>
</ResourceDictionary.MergedDictionaries>
<SolidColorBrush x:Key="NavigationPaneText" Color="{ThemeResource NavigationPaneTextColor}"/>
<SolidColorBrush x:Key="NavigationPaneButton" Color="{ThemeResource NavigationPaneButtonColor}"/>
</ResourceDictionary>
And Styles knows about AppTheme:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestImage.Resources">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ms-appx:///Resources/AppTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="Button" x:Key="WasHamburguerButton">
<Setter Property="Background" Value="{ThemeResource NavigationPaneButton}" />
<Setter Property="Foreground" Value="{ThemeResource NavigationPaneText}"/>
</Style>
</ResourceDictionary>

CalendarStyle of DatePicker different than my custom CalendarStyle

I have a custom Calendar style and a custom DatePicker style.
Code in my MyCustomSkin.xaml (from my library project)
<Style TargetType="{x:Type Calendar}">
<Setter Property="Background" Value="Red"/>
</Style>
<Style TargetType="{x:Type DatePicker}">
<Setter Property="Background" Value="Green"/>
</Style>
They are both inside my MyCustomSkin.xaml ResourceDictionary (separate solution that generate a MyCustomSkin.dll) that I reference inside my application.
Code in my App.xaml (from my application)
<Application x:Class="WpfApplication1.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="pack://application:,,,/MyCustomSkin;component/MyCustomSkin.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Code in my MainWindow.xaml (from my application)
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow">
<Grid>
<DatePicker HorizontalAlignment="Right" />
<Calendar HorizontalAlignment="Left"/>
</Grid>
</Window>
When I create a Calendar in my application (without specifying any style), the background is red.
When I am creating a DatePicker in my application (without specifying any style), the background is green but the background of its calendar is the system one (=> not red).
Why? I thougt that I was overriding all the system calendars with mine. Why is it applying the custom style for the Calendar but not on the Calendar of DatePicker?
Thank you!
Your MyCustomSkin.xaml should be:
<Style TargetType="{x:Type Calendar}" >
<Setter Property="Background" Value="Red" />
</Style>
<Style TargetType="{x:Type DatePicker}" >
<Setter Property="Background" Value="Green" />
<Setter Property="CalendarStyle">
<Setter.Value>
<Style TargetType="{x:Type Calendar}" BasedOn="{StaticResource {x:Type Calendar}}"/>
</Setter.Value>
</Setter>
</Style>
DatePicker has a default CalendarStyle which will be applied on component initialization.

Categories

Resources