I'm starting to use styles in WPF. I'm using MahApps styles as a base, which so far has been really good. I've been able to make specific modifications using the BasedOn property.
One of the simpler changes is to add a default margin so when adding controls they don't touch. It's worked really well so far until I tried to use the MetroCheckBox. With this specific control it throws an xaml parse exception: "Cannot find resource named 'MetroCheckBox'. Resource names are case sensitive."
I had a look in the source code, trying to track down this issue and coppied the name directly from the GitHub:
https://github.com/MahApps/MahApps.Metro/blob/master/MahApps.Metro/Styles/Controls.CheckBox.xaml
It's definately and all my other controls work fine:
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource MetroButton}">
<Setter Property="Margin" Value="2"/>
</Style>
<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource MetroComboBox}">
<Setter Property="Margin" Value="2"/>
</Style>
<Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource MetroCheckBox}">
<Setter Property="Margin" Value="2"/>
</Style>
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource MetroTextBox}">
<Setter Property="Margin" Value="2"/>
</Style>
Any ideas on how to fix this?
Note, I'm including the reference to the styles like so:
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:extra="http://schemas.extra.com/ui"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:visualizationToolkit="clr-namespace:System.Windows.Controls.DataVisualization;assembly=System.Windows.Controls.DataVisualization.Toolkit"
xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"
xmlns:Primitives="clr-namespace:System.Windows.Controls.DataVisualization.Charting.Primitives;assembly=System.Windows.Controls.DataVisualization.Toolkit"
xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
xmlns:Custom="http://metro.mahapps.com/winfx/xaml/controls"
x:Class="MyApp.App"
StartupUri="/MyApp;component/GUI/Window/Window3.xaml"
>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<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" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource MetroButton}">
<Setter Property="Margin" Value="2"/>
</Style>
<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource MetroComboBox}">
<Setter Property="Margin" Value="2"/>
</Style>
<!--<Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource MetroCheckBox}">
<Setter Property="Margin" Value="2"/>
</Style>-->
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource MetroTextBox}">
<Setter Property="Margin" Value="2"/>
</Style>
<!--Chart Style-->
<Style TargetType="{x:Type chartingToolkit:Chart}
...
</Style>
<!--Top Tab Item-->
<Style x:Key="TopTabItemStyle" TargetType="{x:Type TabItem}" BasedOn="{StaticResource {x:Type TabItem}}">
...
</Style>
<!--Tab Item-->
<Style TargetType="{x:Type TabItem}" BasedOn="{StaticResource MetroTabItem}">
...
</Style>
<!-- Group Box-->
<Style TargetType="{x:Type GroupBox}" BasedOn="{StaticResource MetroGroupBox}">
<!--<Setter Property="Margin" Value="5"/>
<Setter Property="Padding" Value="5"/>
<Setter Property="Foreground" Value="{DynamicResource BlackBrush}"/>
<Setter Property="Background" Value="{DynamicResource AccentColorBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource AccentColorBrush}"/>
<Setter Property="Custom:ControlsHelper.HeaderFontSize" Value="{DynamicResource ContentFontSize}"/>
<Setter Property="Custom:GroupBoxHelper.HeaderForeground" Value="{x:Null}"/>-->
<Setter Property="Custom:ControlsHelper.HeaderFontWeight" Value="SemiBold"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupBox}">
<Grid x:Name="GroupBoxRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0,0,0,2" Background="Transparent" Grid.Row="0">
<ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" TextElement.FontWeight="{TemplateBinding Custom:ControlsHelper.HeaderFontWeight}" TextElement.FontStretch="{TemplateBinding Custom:ControlsHelper.HeaderFontStretch}" TextElement.FontSize="{TemplateBinding Custom:ControlsHelper.HeaderFontSize}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True"/>
</Border>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0" Background="Transparent" Grid.Row="1">
<ContentPresenter Cursor="{TemplateBinding Cursor}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Margin="{TemplateBinding Padding}"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</Application.Resources>
You are missing the required ResourceDictionary to bring in the styles for the MahApps. You can do by including the ResourceDictionary definition in the XAML of either the XAML file where you are composing your view or you can add it to the APP.XAML file - the later will give you better performance in the short term.
For example: here is the MahApps controls xaml included with other MahApps resource dictionaries, the controls xaml is the one you need in this case:
<Application x:Class="MyApp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<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" />
<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>
</Application>
I ran it today and it works fine:
<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource MetroComboBox}">
<Setter Property="Margin" Value="2"/>
</Style>
As far as I can tell I've changed nothing to do with the project or references.
However, in the last few days Visual Studio had corrupted somehow with the designer throwing exceptions left right and center, solution explorer failing to display anything (was fixed after clearing Component Model Cache) and NuGet failing to work for me to check the MahApps version.
So I set off the installer on a repair install, and now the style works fine.
I have no idea if these are connected... but they may be, so I'll leave this up as an answer in case anyone else comes across this same issue.
This can be caused if you upgrade from a version of MahApps prior to 2.0 to a more recent version.
For more details, see:
mahapps.com: Migration to v2.0 - MahApps.Metro
https://mahapps.com/docs/guides/migration-to-v2.0
Related
This question already has answers here:
Overriding application wide style
(2 answers)
Closed 3 years ago.
I'm in pretty new to C# WPF and recently meet a very weird problem.
I'm managing style sheet xaml files as following pictures and code.
File Structure
[ App.xaml ]
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/StyleText.xaml"/>
<ResourceDictionary Source="Styles/StyleButton.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
[ StyleText.xaml ]
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Red"/>
</Style>
[ StyleButton.xaml]
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<TextBlock x:Name="TblockTest" Background="Gray" Foreground="Blue">
<TextBlock.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Green"/>
</Style>
</TextBlock.Resources>
<ContentPresenter x:Name="CpCustomButton" ContentSource="Content"/>
</TextBlock>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="False">
<Setter TargetName="CpCustomButton" Property="TextBlock.Foreground" Value="Black"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
These are test codes to reproduce the problem.
What I want to do is ignore the style of StyleText.xaml inside StyleButton.xaml without addressing key to the textblock style in StyleText.xaml
As you know, textblock style without key will serve the global style, and so I don't have to insert annoying 'style={~~}' code per textblock.
But now, I can't avoid that it infects the style of textblock inside of control template for other control like button.
As you can see in the StyleButton.xaml, I tried several things that I can think and googled so much times, but nothing solves this problem clearly.
The content of a button always shows in Red which is the color addressed by StyleText.xaml.
What should I do to solve the problem?
I also attach my test solution noted above.
https://www.dropbox.com/s/no0j60px2qnl51y/WeirdProblem.zip
Thanks to read.
I downloaded the solution and here's a fix: move the TextBlock Foreground style from the TextBlock.Resources to ContentPresenter.Resources like this
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<TextBlock
x:Name="TblockTest"
Background="Gray"
Foreground="Blue">
<ContentPresenter x:Name="CpCustomButton" ContentSource="Content">
<ContentPresenter.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Green" />
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</TextBlock>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="False">
<Setter TargetName="CpCustomButton" Property="TextBlock.Foreground" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I'm not sure why it didn't use the style from the TextBlock.Resources when that is a parent to the ContentPresenter.
Hope that helps. Michal
I am designing a revit addin.I'm using WPF and I want to design style templates which can then be inherited by all WPF pages.I have read that I need to put the styles in app.xaml but there is no app.xaml as this is an addin.
As of now,I'm creating style templates but one template can only be used by the elements of that particular page.
I want to create a style template which every page can inherit without app.xaml.How do I do that?
If all you need is to share styles and maybe some resources you can do it without an App.xaml. In your project, create a xaml file to contain the shared styles and call it something like "MyCommonResources.xaml". It should simply contain a resource dictionary that holds the shared styles/resources. For example:
<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"
xmlns:local="clr-namespace:MyAppNS">
<SolidColorBrush x:Key="Window.Background" Color="#FF202020"/>
<SolidColorBrush x:Key="MyTitleBar.Background" Color="#FF5A5A5A"/>
<SolidColorBrush x:Key="MyTitleBar.Foreground" Color="WhiteSmoke"/>
<SolidColorBrush x:Key="MyTitleBar.Disabled.Background" Color="Black"/>
<SolidColorBrush x:Key="MyTitleBar.Disabled.Foreground" Color="Gray"/>
<Style x:Key="CommandButtonStyle" TargetType="Button">
<Setter Property="MinHeight" Value="40"/>
</Style>
<Style x:Key="MyTitleBarStyle" TargetType="Label">
<Setter Property="Background" Value="{StaticResource MyTitleBar.Background}"/>
<Setter Property="Foreground" Value="{StaticResource MyTitleBar.Foreground}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="MinHeight" Value="34"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="{StaticResource MyTitleBar.Disabled.Background}"/>
<Setter Property="Foreground" Value="{StaticResource MyTitleBar.Disabled.Foreground}"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
now in your xaml for the Window/Page/UserControl add a resource section and merge this dictionary in with the local...
<Window x:Class="MyAppNS.MyWPFWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MyAppNS"
mc:Ignorable="d">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MyCommonResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="MyLocalStyle" TargetType="Button">
<Setter Property="VerticalContentAlignment" Value="Left"/>
</Style>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Content="This is the Title"
Style="{StaticResource MyTitleBarStyle}"/>
<Button x:Name="btnOK" Grid.Row="1" Content="OK"
Style="{StaticResource CommandButtonStyle}"
Click="btnOK_Click"/>
</Grid>
</Window>
Excuse me for any typos in the above, cut & pasted it from a Winforms app I have but quickly edited it down so it wouldn't be so large and changed some names to make better sense.
Do you have a WPF project or just a WPF view in a Forms application?
Maybe this contribution will help you ->
App.XAML where are you?
I have 2 ComboBox-Styles in my WPF-Application. They're look both like this:
<Style TargetType="{x:Type local:MyComboBox1}">
<Style.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
...
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Style.Resources>
<Setter Property="SnapsToDevicePixels" Value="true" />
...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyComboBox1}">
...
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers />
</Style>
Now I want to style the ComboBoxItems for each ComboBox in a different way. How can i do this?
You can use the ItemContainerStyle property
<Style TargetType="Combobox" x:Key="myStyleOne">
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ComboBoxItem">
<!-- put your style here -->
</Style>
</Setter.Value>
</Setter>
</Style>
And then you can use your style like the following.
<ComboBox Style="{StaticResource myStyleOne}" />
I've search around here on SO and what not able to find a clear answer explaining how to setup a 'style resource'. In my case my dialog controls several buttons and lists, and other various controls which I want to set a generic theme/style for. Similar to how you would do using a CSS file in HTML.
For the sake of simplicity in this example I have a style i want to use across the board on all my buttons. However I would prefer not to contain all these style resources in the xaml of my UI layout. I would like to move the styles to a general xaml resource file which would contain just the styles, that way i could also easily reference them into other wpf dialogs throughout the tool.
How do I set this up to make use of a general resource file containing styles for the various controls in my tool? Then be able to reference and use that style in my xaml UI's.
Thank you
<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" Height="200" Width="200">
<Window.Resources>
<Style TargetType="Button" x:Key="CoolButton" >
<Setter Property="Margin" Value="1,2,1,2"/>
<Setter Property="Background" Value="LightBlue"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="FontSize" Value="12" />
<Setter Property="FontFamily" Value="Calibri" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}"
BorderBrush="Lavender" BorderThickness="5" CornerRadius="6,0,6,0" x:Name="bd">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="White" />
<Setter Property="Cursor" Value="Hand" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<Button Style="{StaticResource CoolButton}" Content="Button" Margin="2" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75"/>
<Button Style="{StaticResource CoolButton}" Content="Button" Margin="2" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75"/>
<CheckBox Margin="2" Content="Great"></CheckBox>
</StackPanel>
</Window>
On a side note why does this not work to use variables for colors in the resource style xaml?
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!--COLORS-->
<Color x:Key="AccentColor">#CC4021</Color>
<Style TargetType="Button">
<Setter Property="Foreground" Value="{StaticResource AccentColor}"/>
</Style>
</ResourceDictionary>
There are a few steps to follow from making a instance-specific style a generic style.
Remove the Key. This will make the style to be used for every button:
<Style TargetType="Button">
Move it to a resource file, for example Default.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Style TargetType="Button">
...
</Style>
</ResourceDictionary>
Include a reference to the resource from a central point, for example the App.xaml, which will load the resources. The App.xaml will cause the styles to be used application-wide in just one go:
<Application x:Class="..."
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Default.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
I have the following LAFs ("Look And Feel" ,From Java's Swing) in two different projects :
Type 1 :
Type 2 :
I would like to know how I can switch between these and other LAFs.
Thanks in advance.
The easiest, most maintainable method that I'm aware of for quickly swapping in different visual styles is to use Styles in an external ResourceDictionary. For the example below you would create a new solution folder called 'Skins', then add a new class called 'MainSkin.xaml'.
MainWindow.xaml
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<TextBlock Style="{StaticResource TextBlockV1}" Text="This is some text." />
</Grid>
Skins\MainSkin.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="TextBlockV1" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Comic Sans MS" />
<Setter Property="FontSize" Value="14" />
</Style>
<Style x:Key="TextBlockV2" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="FontFamily" Value="Courier New" />
<Setter Property="FontSize" Value="30" />
</Style>
<Style x:Key="TextBlockV3" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="FontFamily" Value="Times New Roman" />
<Setter Property="FontSize" Value="8" />
</Style>
</ResourceDictionary>
Change look and feel in WPF application?
This directs you to WPF Toolkit which shows you how to set themes in the xml for a page.