Use ResourceDictionary with other Styles in WPF - c#

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>

Related

WPF Styling : Resource not found; ResourceKey

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.

Change Font Size of all UI Elements in using Static Resource from App.xaml in WPF

I'm need to change the font size of all text across the application.
I have tried doing as follows, but that doesn't work:-
<Style x:Key="fontsize" TargetType="{x:Type FrameworkElement}">
<Setter Property="Control.FontSize" Value="20"/>
</Style>
<Style TargetType="{x:Type FrameworkElement}" BasedOn="{StaticResource fontsize}"/>
When I try setting as follows then that works fine but doesn't get applied to all elements & needs to apply that for all different types of elements aperately.
<Style TargetType="TextBlock" BasedOn="{StaticResource fontsize}"/>
<Style TargetType="TextBox" BasedOn="{StaticResource fontsize}"/>
<Style TargetType="DataGridCell" BasedOn="{StaticResource fontsize}"/>
<Style TargetType="MenuItem" BasedOn="{StaticResource fontsize}"/>
<Style TargetType="DatePicker" BasedOn="{StaticResource fontsize}"/>
Also I would like to ask that, is there a way that I can override the Global Style for a particular element, like Heading text should be of different size on a user control?
in App.xaml
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="20"/>
<Setter Property="FontWeight" Value="Bold"/>
</Style>
Create a global style for the window in App.xaml.
<Application.Resources>
<Style x:Key="WindowStyle" TargetType="{x:Type Window}">
<Setter Property="FontStyle" Value="Italic" />
<Setter Property="FontSize" Value="24" />
<Setter Property="Foreground" Value="Green"/>
</Style>
</Application.Resources>
and set that style for the required windows.
<Window x:Class="YourNamespace.MainWindow" Style="{StaticResource WindowStyle}".....>
for overriding the style for a usercontrol
<local:UserControl1>
<local:UserControl1.Style>
<Style TargetType="UserControl">
<Setter Property="FontSize" Value="10"/>
</Style>
</local:UserControl1.Style>
</local:UserControl1>
There are two controls this involves.
You're maybe thinking "hey what about this cell or that calendar".
Their templates show text in a textblock.
When you set Header on a menuitem or content on a label, you get a textblock generated.
You therefore "only" need to set style on both textblock and textbox:
<Application.Resources>
<ResourceDictionary>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="20"/>
</Style>
<Style TargetType="TextBox">
<Setter Property="FontSize" Value="20"/>
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>
Having said that.
As Clemens pointed out.
The Font size and styling dependency properties are marked as inherits, so if you just have mainwindow then you could just set on that.
It's not just "obvious" that a label ends up with a textblock in it when you set content though. Similarly a menuitem and header. Hence I thought it worth posting this answer.

Can't use XAML ResourceDictionary in a C# / WPF class library [duplicate]

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>

WPF :Material Design + dragablz tabItem header style

I am working in WPF with the MaterialDesign Toolkit and Dragablz.
I encountered a problem while trying to style a TabablzControl.
I already have style for the windows default TabControl and TabItem header, as shown in the picture:
http://i.imgur.com/2anl5rl.png
But when I change the default tabControl to TabablzControl, it turns into this:
http://i.imgur.com/bhaaMVy.png
Here are the window.resources:
<Style x:Key="mdTabControl" TargetType="TabControl">
<Setter Property="TextElement.Foreground" Value="{DynamicResource MaterialDesignBody}"/>
<Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}"></Setter>
</Style>
<Style x:Key="mdTabHeader" TargetType="{x:Type TabItem}">
<Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}"></Setter>
<Setter Property="Foreground" Value="{DynamicResource MaterialDesignBody}"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border Name="Border" Margin="1,0,1,0" CornerRadius="3 3 0 0">
<ContentPresenter x:Name="ContentSite" VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header" Margin="10,2,10,2"
RecognizesAccessKey="True">
</ContentPresenter>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Panel.ZIndex" Value="100" />
<Setter TargetName="Border" Property="Background" Value="{StaticResource SecondaryAccentBrush}" />
<Setter Property="Foreground" Value="{StaticResource SecondaryAccentForegroundBrush}"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Panel.ZIndex" Value="100" />
<Setter TargetName="Border" Property="Background" Value="{StaticResource PrimaryHueMidBrush}" />
<Setter Property="Foreground" Value="{StaticResource PrimaryHueMidForegroundBrush}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="{StaticResource PrimaryHueDarkBrush}" />
<Setter Property="Foreground" Value="{StaticResource PrimaryHueDarkForegroundBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The error appears when I change the mdTabControl style targetType to:
TargetType="dbz:TabablzControl"
I want to keep the style I set to the TabControl, but with the added functionality of the TabablzControl
Any help will be appreciated
First thing to note, which is a general WPF characteristic, you are not using style inheritance correctly.
As you are using Material Design with Dragablz, if you are restyling the tab control itself, you must inherit from the Material Design style in the Dragablz assembly using BasedOn:
<Style x:Key="mdTabControl" TargetType="TabControl" BasedOn="{StaticResource MaterialDesignTabablzControlStyle}">
<Setter Property="TextElement.Foreground" Value="{DynamicResource MaterialDesignBody}"/>
<Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}"></Setter>
</Style>
Again, with the tab header itself, you need to inherit from the relevant style:
<Style x:Key="mdTabHeader" TargetType="{x:Type TabItem}" BasedOn="{StaticResource MaterialDesignDragableTabItemStyle}">
. . .
</Style>
Note, that (depending you your App.xaml setup) you probably need to make sure the correct resource dictionary is included in the same XAML file. For example a more complete XAML might be:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Dragablz;component/Themes/materialdesign.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style x:Key="NormalTabItemStyle" TargetType="{x:Type dragablz:DragablzItem}" BasedOn="{StaticResource MaterialDesignDragableTabItemStyle}">
<Setter Property="Width" Value="280" />
<Setter Property="Padding" Value="1" />
</Style>
. . .
</ResourceDictionary>
</Window.Resources>
Finally, as you are changing the TabItem style, you either need to the TabablzCOntrol style the correct style, or you could use it where you actually declare the TabablzControl itself:
<dragablz:TabablzControl ItemContainerStyle="{StaticResource mdTabHeader}" />
A good example of all this in action is in the SidePanels project in the demo solution at: https://github.com/ButchersBoy/DragablzSamplez
<Style TargetType="{x:Type dragablz:TabablzControl}" BasedOn="{StaticResource MaterialDesignTabablzControlStyle}"/>

WPF - Modify MahappsMetro DataGrid style

I'm currently working with MVVM in WPF, I installed MahappsMetro in my project. I want to change the default DataGrid style, without losing all the properties of MetroDataGrid style (Style for DataGrid from MahappsMetro).
I simply want to change some Triggers as IsMouseOver and IsSelected, I tried doing this:
I defined this Style in App.xaml
<Style x:Key="TransparentDataGrid" TargetType="{x:Type DataGrid}" BasedOn="{StaticResource MetroDataGrid}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGrid}">
<DataGrid>
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
</DataGrid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And I bind this Style, where I need it
Style="{DynamicResource TransparentDataGrid}"
But I get the exception :
A first chance exception of type 'System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll
Also I tried :
I created the style in MainViewModel.xaml but I don't know how to bind this style to other views.
to derive from existing style for the controls you need to specify the type as the key in based on attribute
<Style x:Key="TransparentDataGrid" TargetType="{x:Type DataGrid}" BasedOn="{StaticResource {x:Type MetroDataGrid}}">
<Setter Property="Template">
<Setter.Value>
...
if above does not work then do prefix with correct namespace to MetroDataGrid eg mapp:MetroDataGrid where mapp points to MahappsMetro assembly
eg
<Application x:Class="CSharpWPF.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
xmlns:mapp="clr-namespace:MahApps.Metro.Controls">
<Application.Resources>
<Style x:Key="TransparentDataGrid" TargetType="{x:Type DataGrid}" BasedOn="{StaticResource {x:Type mapp:MetroDataGrid}}">
<Setter Property="Template">
<Setter.Value>
...
</Application.Resources>
use the correct assembly above is just an example

Categories

Resources