How to Disable Material Design Style in WPF - wpf

I am using Material Design in XAML to style my WPF UI controls. I defined the default theme in the App.xaml file.
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<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.DeepPurple.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
However, I want some of my controls to have the default WPF look and feel, but it looks like the Material Design in XAML overrides the WPF default control style.
Example: The button below automatically takes its style from the Material design without specifying it.
<Button Content="Hello" Width="100"/>
How can I disable the Material Design in some controls?

Setting the Style property to x:Null makes it fall back to the default Style that is implemented in the framework assembly:
<Button Content="Hello" Width="100" Style="{x:Null}" />
The other option would be to remove the <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" /> from your App.xaml and explicitly set the Style property of all controls that do you want to have the Material Design look.

You can create an empty style inside a ResourceDict like this:
<Window.Resources>
<ResourceDictionary>
<Style x:Key="styleless" />
</ResourceDictionary>
</Window.Resources>
and assign it to your button like this:
<Button Style="{StaticResource styleless}" />

Related

Changing UI Style in MahApps.Metro MessageDialog buttons

I have a custom theme for my application and I would like to change the Style of the buttons (color, border, etc..) of the Buttons generated by the MessageDialog to match my application theme. Is there a simple way to do this in XAML ?
If you set your application theme in the app.xaml like below the standard mahapps.metro styles usually do a pretty good job of matching the application (including the mahapps MessageDialog).
app.xaml
<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/Red.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
sample button styles
<Button Style="{DynamicResource AccentedSquareButtonStyle}" />
<Button Style="{DynamicResource MetroCircleButtonStyle}"/>
You can also change styles if sections of your code
<StackPanel>
<StackPanel.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/FlatButton.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</StackPanel.Resources>
</StackPanel>
You should check out MahMappsmetro and their Github
Hope that is what you were asking.

Override FontStyle for all Controls

is there a way to set default FontStyle for any controls in the application.
I set default style for TextBlock in the Generic.xaml but when I set in the application any property of the textBlock then it start using the main parrent style for it, but not mine style with changed some properties.
Is there a way to set my style as the main style for all TextBlocks?
Yes there is. Simply, create a "anonymous" style and load it in the App.xaml. You may want to have a look here. In the following you can find the approach I use, usually.
Style.xaml
<ResourceDictionary ...>
<!-- a non anonymous style as base for all styles you may want to derive -->
<Style x:Key="TextBlockDefault" TargetType="TextBlock">
<!-- every default property you want to set -->
</ Style>
<!-- now the anonymous style (no key attribute) -->
<Style BasedOn="{StaticResource TextBlockDefault}" TargetType="TextBlock" />
</ResourceDictionary>
App.xaml
<Application ...>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/<yourAppName>;component/<path>/Style.xaml" />
</ ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

How should application wide resources be organized?

Here is the scenario:
I have been using VS 2010 to write quite a large WPF project using MEF. There are multiple projects within this solution and I have one ResourceDictionary for all of my styles.
The AppStyles.xaml ResourceDictionary is located in my startup project, it contains all of my styles for the project. And within my App.xaml I have the following:
<Application x:Class="Dionysus.Shell.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DispatcherUnhandledException="UnhandledException" ShutdownMode="OnMainWindowClose">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="AppStyles.xaml"/>
</ResourceDictionary>
</Application.Resources>
Now, this all works perfectly in design mode of VS 2010 and when I am debugging, the correct styles are being applied to all of my controls. But I recently switched to VS 2012, and the designer is no longer working! When I debug it works perfectly but whenever I use one of my styles as follows:
<Button Name="btnForward" Height="23" Margin="10,0" Style="{StaticResource DionysusButton}" Grid.Row="2" Grid.Column="0"/>
I get the following error in the VS 2012 designer:
The resource "DionysusButton" could not be resolved.
I am clueless as to why this is happening, I have renamed my Style, and even the ResourceDictionary to no avail.
Is there a different way I should be doing this in VS 2012 or is this a problem with VS 2012?
I have found a lot of posts that say that changing the x:Name property of my AppStyles.xaml ResourceDictionary to x:Key will resolve this problem but I cannot do that as it is not a valid option for a ResourceDictionary.
Thanx in advance
-- UPDATE
I am using Marc's answer and all seems to be going well except for default styles. I have the following style:
<Style TargetType="DataGrid" x:Name="DataGridStyle"/>
And this is my main ResourceDictionary:
<ResourceDictionary x:Name="Main"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/AppStyling.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style TargetType="DataGrid" BasedOn="{StaticResource DataGridStyle}"/>
When I do not add the Style tag in my main ResourceDictionary it works fine, but the style is not being applied to all items obviously. When I do add it, i get the following exception:
Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an exception
Ideas?
Are you trying to use the styles which are located in your app.xaml in your modules which you export into the shell using PRISM? The modules should not have a reference to your application/shell project (the startup project)? Then they maybe just don't 'know' the project, which contains the styles? Though the question is why it works in VS2010 then... Please let me know, if I misunderstood your MEF scenario, I'll adapt my answer then.
Resources and Prism is abit tricky, and I am a fan of the following approach, which I have posted before, but it might help in your case too. It is much more appropriate for a PRISM solution than placing your resources inside app.xaml:
I usually create a seperate styling project, which I reference from the projects, which I want to style. The styling project has a fixed structure like this:
For every control, I create a styling ResourceDictionary. For example for my buttons:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="PrimaryButtonStyle" TargetType="Button">
</Style>
<Style x:Key="ToolbarButton" TargetType="Button">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Margin" Value="3"/>
<Setter Property="Background" Value="Transparent"></Setter>
</Style>
</ResourceDictionary>
In one main ResourceDictionary, I merge all the other dictionaries, in this case in the file IncaDesign.xaml, which you can see in the picture above:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:Commons.Controls;assembly=Commons">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Converter/Converter.xaml" />
<ResourceDictionary Source="Styles/Button.xaml" />
<ResourceDictionary Source="BitmapGraphics/Icons.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- Default Styles -->
<Style TargetType="Button" BasedOn="{StaticResource PrimaryButtonStyle}"></Style>
</ResourceDictionary>
Notice how I defined the default styles, which are applied automatically, unless you specify otherwise. In every window or control, that you want to style, you only need to reference this one ResourceDictionary. Note the definition of the source, which is a reference to the assembly (/Commons.Styling;component...)
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Commons.Styling;component/IncaDesign.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- Here you can added resources which belong to the UserControl only -->
<!-- For example: -->
<DataTemplate x:Kex="UcTemplate" />
</ResourceDictionary>
</UserControl.Resources>
Default styles will be set automatically now, and if you want to access a resource explicitly, you can do this, using StaticResource.
<Viewbox Height="16" Width="16" Margin="0,0,10,0">
<ContentControl Content="{StaticResource FileIcon32}" />
</Viewbox>
This is very nice solution in my opinion, which works for very complex solutions, including modular solutions, for example built with PRISM.

WPF resource merged to Application.Resources but not resolved at runtime

I have a brush that is part of a ResourceDictionary that is merged to Application.Resources.
But for some reason it's not resolved at runtime when a style is being applied to one of the controls. However, if I call Application.Current.FindResource("BrushName") from the Immediate Window at the time when exception is thrown, the resource is found.
Am I missing something? Isn't WPF supposed to try to look for the resource in the app's resources?
UPDATE
The application is quite big, so I can't post all actual code but here's the way the resources are merged and used:
Brushes.xaml
<ResourceDictionary ...>
<SolidColorBrush x:Key="BrushName" Color="#12345678" />
</ResourceDictionary>
SomeStyles.xaml
<ResourceDictionary ...>
<Style x:Key="SomeStyle">
<Setter Property="SomeProperty" Value="{StaticResource BrushName}" />
</Style>
</ResourceDictionary>
App.xaml
<Application ...>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Brushes.xaml" />
<ResourceDictionary Source="SomeStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application ...>
And then some control might use the style using the resource like this:
...
Style={StaticResource SomeStyle}
...
UPDATE
It seems to happen to menus and controls that are created in code. Can it be related to those controls and menus not being parts of any window's visual tree?
Your SomeStyle.xaml dictionary needs to reference Brushes.xaml dictionary directly, like so:
<ResourceDictionary ...>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Brushes.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style x:Key="SomeStyle">
<Setter Property="SomeProperty" Value="{StaticResource BrushName}" />
</Style>
</ResourceDictionary>
StaticResources only search up the tree of the current dictionary, so you need to pass in any resources that it needs to reference.
Are you using DynamicResource in the XAML mark up extension?
Your xaml should be {DynamicResource brushName} not {StaticResource brushName}

WPF: Restyle all controls with scroll bars

How can I change the style -ONCE- for the scrollbars shown by all controls (listbox, treeview, scrollbarviewer, richtextbox, etc...)?
If you will define your Style for a control with no x:Key attribute, it will be applied for all instances of that control.
Try like this:
<Window.Resources>
<Style TargetType="ScrollBar">
<Setter Property="Background" Value="Red"/>
</Style>
</Window.Resources>
<Grid>
<TextBox Margin="24,12,0,0" VerticalScrollBarVisibility="Visible" AcceptsReturn="True" Height="28" VerticalAlignment="Top" HorizontalAlignment="Left" Width="89" />
<ScrollBar Name="scroll" HorizontalAlignment="Right" />
</Grid>
Here you can see that the Style is defined for ScrollBar control and have no x:Key attribute defined so it gets applied to the each ScrollBar instance within Window. Like ScrollBar of TextBox and ScrollBar named scroll also.
Hope this helps!
Thanks. Finally the problem was solved by setting the style in the Themes/Generic.xaml and (because of custom controls existing in another assembly with they respective resources merged) adding the following to App.xaml...
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes/Generic.xaml"/>
<ResourceDictionary Source="MyCtls/MyRes.xaml" />
</ResourceDictionary>
</Application.Resources>
The key point is to merge the Generic.xaml file.
Also, if the resource dictionary is in another assembly, it must be referenced as...
<ResourceDictionary Source="pack://application:,,,/OtherAssembly;component/MyCtls/MyRes.xaml"/>

Resources