Adding custom styles to Mahapps.Metro existing ones - c#

I use MahApps.Metro. In the guide to setting it up, it tells you to include some code into the App.xaml. So I did.
Now I wanted to be able to add my own styles to it. This for instance includes all windows to have a border by default.
But that doesn't work. Borders are not applied. I know how to style stuff when not using MahApps.Metro, but with it, I can't get both working.
What's wrong here?
<Application x:Class="ProjectName.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Windows/MainWindow.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" />
<!-- This is what I added -->
<ResourceDictionary xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro">
<Style TargetType="Controls:MetroWindow">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="{DynamicResource AccentColorBrush}" />
</Style>
</ResourceDictionary>
<!-------------------------->
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

You have forgotten to inherit the style with BasedOn:
<ResourceDictionary xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro">
<Style TargetType="Controls:MetroWindow"
BasedOn="{StaticResource {x:Type Controls:MetroWindow}}">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="{DynamicResource AccentColorBrush}" />
</Style>
</ResourceDictionary>
EDIT
after tested it out, my first answer is not really correct. you must set a x:Key and use this key in every MetroWindow xaml.
<Style x:Key="CustomGlobalMetroWindow"
TargetType="{x:Type Controls:MetroWindow}"
BasedOn="{StaticResource {x:Type Controls:MetroWindow}}">
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="BorderBrush"
Value="Purple" />
</Style>
usage
<Controls:MetroWindow x:Class="Demo"
Style="{DynamicResource CustomGlobalMetroWindow}" />
Hope that helps!

I ended up doing it this way:
Less errorprone and more laziness-friendly
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
ThemeManager.ChangeAppStyle(this,
ThemeManager.GetAccent("Amber"),
ThemeManager.GetAppTheme("BaseDark"));
var allTypes = typeof(App).Assembly.GetTypes();
var filteredTypes = allTypes.Where(d =>
typeof(MetroWindow).IsAssignableFrom(d)
&& typeof(MetroWindow) != d
&& !d.IsAbstract).ToList();
foreach (var type in filteredTypes)
{
var defaultStyle = this.Resources["MetroWindowDefault"];
this.Resources.Add(type, defaultStyle);
}
base.OnStartup(e);
}
}

Related

System.Windows.Markup.XamlParseException on a Multi Project Solution (Mixed platforms)

I've integrated my WPF project into a mixed solution. This solution has 3 projects written in WinForms (.cs), 1 writtenin WinForms (.vb) and the mine one written in WPF (using MahApps).
The Owner of my project/windows must be the one of the three written in WinForm.
I've made a call like this:
using WPFSolution;
using System.Windows.Forms.Integration;
private void buttonOpenWPFUi_Click(object sender, EventArgs e)
{
var pm = new ProductsMenu();
ElementHost.EnableModelessKeyboardInterop(pm);
pm.Show();
}
ProductsMenu is my starting point on in the App.xaml
But when I reach the InitializeComponents() of the ProductsMenu.xaml.cs the System.Windows.Markup.XamlParseException were thrown
The error is: IOException: Cannot locate resource 'resources/icons.xaml'.
My App.xaml file:
<Application x:Class="WPFSolution.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="ProductsMenu.xaml" ShutdownMode="OnMainWindowClose">
<Application.Resources>
<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" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.AnimatedTabControl.xaml" />
<!-- Accent and AppTheme setting -->
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Red.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
<!-- BaseDark.xaml | BaseLight.xaml -->
<!-- Icons -->
<ResourceDictionary Source="pack://application:,,,/WPFSolution;component/Resources/Icons.xaml"></ResourceDictionary>
<!-- Languages -->
<!--<ResourceDictionary Source="Resources/StringResources.en.xaml"></ResourceDictionary>-->
<ResourceDictionary Source="Resources/StringResources.it.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type ToolTip}">
<Setter Property="Background" Value="White"/>
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Padding" Value="7,4,7,4"/>
</Style>
<!--IMMAGINI -->
<!--nodi-->
<!--<BitmapImage x:Key="Nodo1" UriSource="Resources/img/TileImages/nodi/nodo1.jpg"></BitmapImage>
<BitmapImage x:Key="Nodo2" UriSource="Resources/img/TileImages/nodi/nodo2.jpg"></BitmapImage>
<BitmapImage x:Key="Nodo3" UriSource="Resources/img/TileImages/nodi/nodo3.jpg"></BitmapImage>
<BitmapImage x:Key="Nodo4" UriSource="Resources/img/TileImages/nodi/nodo4.jpg"></BitmapImage>-->
</ResourceDictionary>
</Application.Resources>
I've tried to set the Icons.xaml/Build Action as Resource and also as Page.
I'm missing something?
Got it (or a workaround at least).
I've dereferenced the WPFSolution Project.
Compiled the WPF solution
as .dll (I've copied all the merged dictionaries to every
window.xaml, removed the app.xaml file and change the application
type to class library)
Copied the WPFSolution.dll in the bin/release
- bin/debug of the main project
Referenced the .dll
Everything worked like a charm
try this syntax :
<ResourceDictionary Source="/WPFSolution;component/Resources/Icons.xaml" />
and also, "Page" is the right build option in this case

How to change the font size in a mahapps project?

So I am trying to change the default font family and the font size in my project. I decided to start with buttons.
I do it like this (I am gonna create a separated file for my style, but now I just want to make it work somehow):
<Controls:MetroWindow.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Templates/MyTemplateSelector.xaml"/>
<ResourceDictionary Source="/Templates/FullMenu.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style BasedOn="{StaticResource MetroButton}" TargetType="Button">
<Setter Property="FontFamily" Value="Calibri" />
</Style>
</ResourceDictionary>
</Controls:MetroWindow.Resources>
and nothing changes. What is wrong?
I guess it's because program can't find "{StaticResource MetroButton}".
App.xaml
<Application x:Class="WpfApp2.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp2"
xmlns:dialogYesNo="clr-namespace:WpfApp2.DialogYesNo"
StartupUri="Views/MainWindow.xaml">
<Application.Resources>
<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 Source="ViewModels.xaml" />
<ResourceDictionary Source="Dialogs.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
So, you just need to use it in App.xaml after declaring metro references:
<Style TargetType="Label">
<Setter Property="FontFamily" Value="Segoe UI Light"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI Light"/>
</Style>
<Style TargetType="TextBox">
<Setter Property="FontFamily" Value="Segoe UI "/>
</Style>
Button uses TextBox, so button will be changed automatically.
Instead of define a style just to set fontfamily/weight you can just define in your resource directly the fontfamily and weight with a key(an example with a font that i use)
<Controls:MetroWindow.Resources>
<FontFamily x:Key="FontAwesome">/tuseradm;component/assets/fontawesome-webfont.ttf#FontAwesome</FontFamily>
</Controls:Flyout.Resources>
then in your button just set the font family
<Button FontFamily="{StaticResource FontAwesome}" Content="" />
EDIT adding another answer:
by default mahapps override the default wpf style. If you want to modify a style for let's say buttons in all your view you don't need to use based on
<Style BasedOn="{StaticResource {x:Type Button}}" TargetType="Button">
<Setter Property="FontFamily" Value="Calibri" />
<Setter Property="FontWeight" Value="ExtraLight"/>
</Style>
EDIT 2
At least for me, even if i see the change at design time using the approach exposed in the first edit, at run time the problem persist. So in my opinion, is much better to stick with my first answer. Maybe it could be annoying to set fontfamily and fontweight for each button, but it is the safest way to deal with mahapps styles. The only way to solve this 100% for sure is to find (no clue where) the template of mahapps buttons and modify it

Catel: Create new DataWindowButtonStyle based on another 3rd party style

REF: Catel docs
Using Visual Studio 2013, .NET 4.5.1, Catel 4.4.
I have a DataWindow with the default Close button. I would like to style that button using the MahApps.Metro Flat Button style. If I had direct access to the DataWindow Close button (I think it's created at runtime), I'd apply the Flat Button style in the XAML, but I don't.
In the Catel docs, the comment says we should specify our own DataWindowButtonStyle. Could I get an example of creating a new DataWindowButtonStyle where I can base it on the MahApps.Metro Flat Button style?
Please let me know if you have any questions or need more information.
Thanks!
Edit: Here's what I've tried:
<catel:DataWindow.Resources>
<!-- Compile Error: A 'DynamicResourceExtension' cannot be set on the BasedOn property of type 'Style'.
<ResourceDictionary>
<Style x:Key="DataWindowButtonStyle" BasedOn="{DynamicResource MetroFlatButton}" />
</ResourceDictionary>
-->
<!-- This compiles and runs, but doesn't work.
<ResourceDictionary>
<Style x:Key="DataWindowButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Yellow" />
</Style>
</ResourceDictionary>
-->
<!-- This compiles and runs, but doesn't work.
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Catel.MVVM;component/themes/generic.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style x:Key="DataWindowButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Yellow" />
</Style>
</ResourceDictionary>
-->
<!-- Compiles and runs, but doesn't work. -->
<Style x:Key="DataWindowButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Yellow" />
</Style>
</catel:DataWindow.Resources>
You can simply define a new DataWindowButtonStyle resource and it should be applied automatically.
The custom DataWindowButtonStyle must be defined in App.xaml application resources.
App.xaml:
<Application.Resources>
<Style x:Key="DataWindowButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Yellow"/>
<Setter Property="Foreground" Value="Red"/>
<Setter Property="MinHeight" Value="50"/>
</Style>
</Application.Resources>
I don't know why setting background property is not working. But other properties are working.

Metro Styles in resource dictionary

I am trying to style my WPF application with Mahapps Metro. I have added the all the needed .xaml files in my MergedDictionary in the App.xaml. If I write the following in a view file,
<Button DockPanel.Dock="Left" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"/>
it works, i.e., the button is styled in the SquareButtonStyle style. But if I instead add the following in my own resource dictionary,
<Style TargetType="Button">
<Setter Property="Style" Value="{DynamicResource SquareButtonStyle}"/>
</Style>
I get an error message,
Setting of the property
"System.Windows.ResourceDictionary.DeferrableContent" has caused an
exception.
(my transation of the German error message). So how can I style all buttons, e.g., with SquareButtonStyle without having to do that on each button individually?
EDIT: Here is my app.xaml (the last dictionary, ResourceDic.xaml, is my own one where the above code is):
<Application xmlns:local="clr-namespace:MGM8" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<local:MGM8_BootStrapper p7:Key="bootstrapper" xmlns:p7="http://schemas.microsoft.com/winfx/2006/xaml" />
</ResourceDictionary>
<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 Source="ResourceDic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Style property can't be set inside Style of any element.
Just declare your style at root level(a root resource Dictionary or App.xmal resources). Just create the style with TargetType Button don't give any key to it. it will be applied to all the buttons in the app.
for ex:
<Style TargetType="Button" BasedOn="{StaticResource SquareButtonStyle}" >
<Setter Property="Height" Value="50"/>
<Setter Property="BorderThickness" Value="2,1" />
</Style>
So above is extending your SquareButtonStyle for your application for all buttons(only if defined at root level).
Update:
You have to use following in your own Resource Dictionary:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="SquareButtonStyle dictionary"/>
</ResourceDictionary.MergedDictionaries>
Then only you can create a button style based on SquareButtonStyle in your ResourceDictionary.

VS2012 The resource "X" could not be resolved

I have a Resources.xaml file in my project that contains a resource dictionary like so:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="GPHeaderFontSize" TargetType="TextBlock">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="FontSize" Value="24" />
<Setter Property="Text" Value="BLAHHHHH"/>
</Style>
</ResourceDictionary>
I have included this dictionary in App.xaml like so:
<Application x:Class="GoldenPlains.App"
xmlns="schemas.microsoft.com/winfx/2006/xaml/presentation";
xmlns:x="schemas.microsoft.com/winfx/2006/xaml";
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone">
<Application.Resources>
<local:LocalizedStrings xmlns:local="clr-namespace:GoldenPlains" x:Key="LocalizedStrings"/>
<ResourceDictionary x:Key="GPResources">
<ResourceDictionary.MergedDictionaries>
<!-- Sometimes VS2012 complaining about path with blue line, please ignore it as path is correct -->
<ResourceDictionary Source="Styles/GPResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="GPRootOverlayBarStyle" TargetType="Image">
<Setter Property="Source" Value="Assets/Images/root_brown_horizontal_bar.png"/>
<Setter Property="Width" Value="729"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Stretch" Value="Uniform"/>
</style>
</Application.Resources>
...
...
</Application>
However when I try to reference an element in the resource dictionary from another Page.xaml file it cannot seem to resolve the resource....
eg:
I have tried using a binding like so:
<TextBlock Style="{Binding Path=LocalizedResources.MyTextBlockStyle, Source= {StaticResource GPResources}}"/>
it does not indicate that something is wrong but nothing shows up on the UI.
A point in the right direction would be great, cheers.
Resource Dictionary definition in the App.xaml should be about like following example :
<Application.Resources>
<ResourceDictionary>
<local:LocalizedStrings xmlns:local="clr-namespace:GoldenPlains" x:Key="LocalizedStrings"/>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/GPResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<!-- Other resources if you have -->
</ResourceDictionary>
</Application.Resources>
Then, when you need to apply style defined in Resources.xaml to a UI control, simply refer to the style's key/name :
<TextBlock Style="{StaticResource GPHeaderFontSize}" />
Notes: All resources need to be inside ResourceDictionary tag, including LocalizedStrings.

Categories