Change Resource Dictionary in runtime - wpf

I use Material design in my wpf. I change theme(Light/Dark) in runtime.
<materialDesign:DialogHost Identifier="RootDialog">
<materialDesign:DialogHost.Resources>
<Style TargetType="materialDesign:Card" BasedOn="{StaticResource {x:Type materialDesign:Card}}">
<Style.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.dark.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Style.Resources>
<Setter Property="Background" Value="{DynamicResource MaterialDesignCardBackground}" />
</Style>
</materialDesign:DialogHost.Resources>
<Grid>
<!--some code-->
</Grid>
</materialDesign:DialogHost>
I want change source of Resource Dictionary in runtime to
pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.light.xaml
How I can do this?

Define your Resource dictionary Apllication wide in App.xaml
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- This is the default theme (useful for Designing)-->
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.dark.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Change the Theme in code behind.
public Skin ChangeSkin()
{
// you might want to have some logic here to keep switching
ApplyResources("pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.light.xaml")
}
private void ApplyResources(string src)
{
App a = App.Current as App;
var dict = new ResourceDictionary() { Source = new Uri(src, UriKind.Relative) };
foreach (var mergeDict in dict.MergedDictionaries)
{
a.Resources.MergedDictionaries.Add(mergeDict);
}
foreach (var key in dict.Keys)
{
a.Resources[key] = dict[key];
}
}

Related

right to left dialog in mahapps

I'm using Mahapps,metro toolkit for create a WPF application.I want to show a right to left dialog.
await this.ShowMessageAsync("This is the title", "Some message");
I am usig above code to create dialog but it is left to right.
This is how to align right in a MessageBox. You should check to see if there is a similar way to do this using MahApps.Metro:
MessageBox.Show("hi", "hey", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK, MessageBoxOptions.RightAlign);
The parameters, in order, are:
Message
Title
Button type
Icon displayed
Button type that is returned by user click
Display options (this is the parameter you are looking for)
This creates the following dialog box:
I found the solution.just add this style to app.xaml
<Style TargetType="{x:Type Dialog:MessageDialog}"
BasedOn="{StaticResource {x:Type Dialog:BaseMetroDialog}}">
<Setter Property="FlowDirection" Value="RightToLeft" />
</Style>
Here is my app.xaml file
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:RandomQuestions"
xmlns:Dialogs="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary >
<Style TargetType="{x:Type Dialogs:MessageDialog}" BasedOn="{StaticResource {x:Type Dialogs:BaseMetroDialog}}">
<Setter Property="FlowDirection" Value="RightToLeft" />
</Style>
<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/Amber.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>

Mixing general WPF styles with ResourceDictionary

I came from web development and WinForms to WPF and maybe I didn't get the concept yet.
I'm able to define general styles for my Application in the app.xaml. For example I defined the style for all my ribbon controls in this file.
Then I tried Microsoft Blend and came across ResourceDictionary, which is somekind of Resource File .resx I knew from WinForms.
But as I see it's not possible to mix these two concepts. For example following xaml code will not work because ResourceDictionary have to be the only child.
<Application x:Class="Wpf.MyApplication.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ribbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
StartupUri="MyMainWindow.xaml">
<Application.Resources>
<!-- Resources scoped at the Application level should be defined here. -->
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/RibbonStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
<BitmapImage x:Key="IconDokumentNeu" >Images/NewDocument_32x32.png</BitmapImage>
<SolidColorBrush x:Key="LightGrayBrushKey">WhiteSmoke</SolidColorBrush>
</ResourceDictionary>
<Style TargetType="{x:Type ribbon:RibbonWindow}">
<Setter Property="Icon" Value="../time2_32.png" />
<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
</Style>
</Application.Resources>
</Application>
It seems I didn't really get the concept. Maybe you can help me, why this is not possible and how I can use general styles next to ResourceDictionary.
You already have resources defined "next to" the dictionary, one image and one brush.
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- Dictionaries from file here -->
</ResourceDictionary.MergedDictionaries>
<!-- Other resources here -->
</ResourceDictionary>
</Application.Resources>
Just include the {x:type} style in the resource dictionary
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- Dictionaries from file here -->
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type ribbon:RibbonWindow}">
<Setter Property="Icon" Value="../time2_32.png" />
<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
</Style>
</ResourceDictionary>

Resources defined in UserControl.Resources can not see elements defined in MergedDictionaries set from code

DefaultStyles contains a DefaultStyle for all TextBoxes:
public partial class UserControl1 : UserControl
{
public UserControl1()
{
Resources.MergedDictionaries.Add(new DefaultStyles());
InitializeComponent();
}
}
Then the Xaml, I inherit the style and add a little more:
<UserControl.Resources>
<Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="Foreground" Value="Green "/>
</Style>
</UserControl.Resources>
This throws a StackOverFlowException as my DefaultStyle is not found, and so it trys to self reference.
Why can't the Style see the default styles in the merged dictionary?
It can't see it because it's essentially replacing it. The InitializeComponent method call will replace the dictionary you refer to in your ctor with the dictionary you define in your XAML.
Basically, you're doing it wrong. Why can't you just do this:
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="DefaultStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
...
</Style>
</ResourceDictionary>
</UserControl.Resources>

Silverlight ResourceDictionary problem

I have reports.xaml page where I have defined some local resources.
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries >
<ResourceDictionary Source="/My.Namespace;component/Resources/Converters.xaml" />
<ResourceDictionary Source="/My.Namespace;component/Resources/GlobResources.xaml" />
<ResourceDictionary Source="/My.Namespace;component/Resources/ReportingResources.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
In the same reports.xaml file I have a content control like so...
<ContentControl
Content="{Binding}"
ContentTemplate="{Binding Converter={StaticResource reportTemplateSelector}, Path=CurrReportType}"
Margin="0"
/>
Now in my converter I load the ReportingResources.xaml resource file with the following lines of code
ResourceDictionary reportTemplate = new ResourceDictionary();
reportTemplate.Source = new Uri("/My.Namespace;component/Resources/ReportingResources.xaml", UriKind.Relative);
template = reportTemplate[Report_Style] as DataTemplate;
return template;
"Report_Style" will actually be a variable that will get set in Convert method of the reportTemplateSelector converter before the above lines get called.
The problem here is that ReportingResources.xaml is dependent on the GlobResources.xaml resource file for some other content. How do I make the content from GlobResources.xaml available to the ReportingResources.xaml file in the lines of code above?
Thanks for your time...
Have you tried....
A resource file can merge other resource files:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ResourceB.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Name="MyButtonStyle" TargetType="Button">
<Setter Property="Background" Value="red"/>
</Style>
</ResourceDictionary>
Taken from Silverlight 3,0 Split styles and templates into different files and merge resources

how do i inherit/overwrite a forced style from a windows theme?

currently i am forcing my WPF app to use the luna theme no matter what, with this XAML code
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles.xaml" />
<ResourceDictionary Source="NavigationCommands.xaml" />
<ResourceDictionary Source="/RibbonControlsLibrary;component/Themes/Office2007Blue.xaml"/>
<ResourceDictionary Source="/PresentationFramework.Luna, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, ProcessorArchitecture=MSIL;;component/Themes/luna.normalcolor.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
and now i want to extend the style of every textbox with this validation trigger
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="Background" Value="#d3e1f3"></Setter>
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
but this trigger does not work, because i forced the luna theme. (without the forced theme every thing works as it should, but doesn't look as it should :( )
is there some way to force the luna theme and extend it's style? probably over the BasedOn property?
atm i defined a key for the style in question and added it to every textbox by hand, that works but isn't the prettiest way to go.
tia
Try
<Style x:Key="{x:Type TextBox}" TargetType="{x:Type TextBox}">
The BasedOn syntax for type styles is as follows:
<Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
HTH
Have you tried to set the lune resourcedictionary first and your own resourcedictionary last?
I can imagine the luna theme overrides your style.
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/PresentationFramework.Luna, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, ProcessorArchitecture=MSIL;;component/Themes/luna.normalcolor.xaml" />
<ResourceDictionary Source="/RibbonControlsLibrary;component/Themes/Office2007Blue.xaml"/>
<ResourceDictionary Source="Styles.xaml" />
<ResourceDictionary Source="NavigationCommands.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Use the mentioned
<Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
but also make sure your dictionaries are included in right order - first the ones you are basing your style on
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/RibbonControlsLibrary;component/Themes/Office2007Blue.xaml"/>
<ResourceDictionary Source="/PresentationFramework.Luna, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, ProcessorArchitecture=MSIL;;component/Themes/luna.normalcolor.xaml" />
<ResourceDictionary Source="Styles.xaml" />
<ResourceDictionary Source="NavigationCommands.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

Resources