How to change XAML value using C#? - c#

I have a style file for Styles in WPF XAML with name Brushes.xaml which stores all colors for the WPF.
Code Here:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Color x:Key="DefaultColor">SteelBlue</Color>
<Color x:Key="LightDefaultColor">LightSteelBlue</Color>
</ResourceDictionary>
I want to change the value of DefaultColor using C# code.

Use the DynamicResource extension instead of the StaticResource extension on all references to keys that can change at runtime.
Then you can use code like the following to change the value.
Application.Current.Resources["Default Color"] = System.Windows.Media.Colors.Red;
This can be done per object to...
public MyWindow()
{
InitializeComponent();
this.Resources["Default Color"] = System.Windows.Media.Colors.Red;
PART_DynamicButton.Resources["Default Color"] = System.Windows.Media.Colors.Red;
}
This is higher performance than clearing your entire merged resource dictionary and adding a new one if you only need to modify a few values.
Just remember that DynamicResource extension only works on DependencyProperties and Freezable objects instantiated in Xaml are usually frozen which prevents modifing their DependencyProperties. So don't try to change the color of a SolidColorBrush if the brush was instaniated in xaml.
Here is a workaround
<! -- Xaml -->
<SolidColorBrush x:Key="App_Page_Background" Color="White"/>
<Page Background="{DynamicResource App_Page_Background}"/>
// C# code
Application.Current.Resources["App_Page_Background"] = new SolidColorBrush(Colors.Red);

Rather than changing the XAML contents you should create one XAML file for each theme.
Then you can change the theme at runtime like this:
ResourceDictionary skin = new ResourceDictionary();
skin.Source = new Uri(#"" + themeName + ".xaml", UriKind.Relative);
Application.Current.Resources.MergedDictionaries.Clear();
Application.Current.Resources.MergedDictionaries.Add(skin);

Related

C# UWP Change global app background

I need to change default white background that is showing on the right side when I am resizing the window of UWP application, and I need to do it dynamically.
I have tried:
var newBackground = Application.Current.Resources["ApplicationPageBackgroundThemeBrush"] as SolidColorBrush;
if (newBackground != null)
{
newBackground.Color = newColor;
}
The newBackground is changed, but not affecting the application.
Any help?
If you want to override ApplicationPageBackgroundThemeBrush
Application.Current.Resources["ApplicationPageBackgroundThemeBrush"] = Colors.Red;
For your issue we need to check something in background:
When you check the ApplicationPageBackgroundThemeBrush in the generaic.xaml(To konw what is generaic.xaml you can see here), you will find that ApplicationPageBackgroundThemeBrush is defined three times in "Default","HighContrast" and also "Light". So that when you call request theme all colors will be changed in different themes.
this.RequestedTheme = ElementTheme.Dark
So go back to your question, if you change the request theme to "Dark" you will find that the change color code:
newBackground.Color = newColor;
will not change since there is a default setting for "Dark".(It works for default/Light theme)
And it seems we cannot modify this theme brush at runtime from code behind.
I think the only way for this is to create theme color yourself then change the color by set the element explictly.
To set the theme color. New acrylic document provide a good point for us. Here I write a simple sample for you to show how default theme works:
Create a dictionary and insert the following code:
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
<SolidColorBrush x:Key="ApplicationPageBackgroundThemeBrush" Color="Blue"></SolidColorBrush>
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="ApplicationPageBackgroundThemeBrush" Color="Yellow"></SolidColorBrush>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
Add it to app.xaml:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
To explictly set the element, do something like mygrid.background=xxxx. If you want to trigger it when resize, change the propery in adaptivetrigger.

Using XAML style on CodeBehind

Guys im trying to using a style from Style.xaml into my code behind
on my style i have a code like this
file Style.xaml
<SolidColorBrush x:Key="FontGrey" Color="#FFC5C0C0"></SolidColorBrush>
and on my Apptest.xaml.cs file i have code like this
txt.Foreground = new SolidColorBrush(Color.FromArgb(255, 252, 147, 25));
if i want to change my foreground color base on style.xaml
how can i do that? i was trying using resources but it doesnt work
note: Style.xaml and Apptest.xaml are separated
You can access your defined resources, in Silverlight, by using the following syntax:
txt.Foreground = (SolidColorBrush)Application.Current.Resources["FontGrey"];
You can put your style into Window.Resources in Apptest.xaml like this:
<ResourceDictionary >
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="Style1.xaml">
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Then in window code behind file Apptest.xaml.cs you can access to resource:
InitializeComponent();
txt.Foreground = Resources["FontGrey"] as SolidColorBrush;
If assume that resources is avaliable, than this code should work for you:
txt.Foreground = (Brush)FindResource("FontGrey");

How to use XAML resource of SolidColorBrush in C#?

I am defining resources in my App.XAML file:
<SolidColorBrush x:Key="ActivePanelBackgBrush" Color="#FF77FF83"/>
<SolidColorBrush x:Key="NonActivePanelBackgBrush" Color="#FFFF7777"/>
In my C# code I would like to set the background of a Grid to that color. How do I do that?
Thx
You can get objects from Resources in App.xaml like that:
var brush = Application.Current.Resources["NonActivePanelBackgBrush"] as SolidColorBrush;
And use it where you want:
Grid1.Background = brush;
Alternatively you can use FindResource.
However, WinRT seemed to be missing the FindResource function which is familiar from WPF. You can use this extension method.( sadly I have not tested it yet)
Grid1.Background = FindResource("NonActivePanelBackgBrush") as SolidColorBrush;

how to create skins for a GUI in WPF?

I was wondering how I should go about creating custom settings for all the color schemes and such. I know I can create styles for individual components or parts..but how should I create a set of skins?
for example, right now I'm using a maroon colored gradientbrush in a lot of subcontrols. However, I'm sure that people other than me will hate the color scheme.
I know that I can create a dependency property on my top level control for the color and then bind the individual parts that need that color to that dependency property. However, there will need to be many properties. Should I just create a separate style object that contains all these properties and place it as field in my user control?
I'm just wondering if there are other ways of doing this in WPF. For example, I guess there could be some way of doing this in xaml or utilizing some built in class in the default libraries.
You can do this by creating new resource dictionary and define there colors and control templates for your controls.
Example you can find in WPF Themes project (download link).
You can change your style by changing resource dictionary, e.g:
<Application x:Class="ThemesSample.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
<ResourceDictionary Source="ExpressionDark.xaml"/>
</Application.Resources>
</Application>
If you want to change theme at runtime you should use following code:
ResourceDictionary dict = new ResourceDictionary();
dict.Source = new Uri("BureauBlack.xaml", UriKind.Relative);
this.Resources.MergedDictionaries.Add(dict);

WPF border background bount to in application resource defined brush won't update when resource is updated

Hi,
so this will be my first question as I did not find anything that could answer my problem.
Initial Situation
I defined a SolidColorBrush in my <Window.Resources>
<SolidColorBrush x:Key="BackgroundBrush" Color="{DynamicResource BackgroundColor}"/>
<Color x:Key="BackgroundColor">PeachPuff</Color>
Then I bound my Border to the SolidColorBrush
<Border Background="{DynamicResource ResourceKey=BackgroundBrush}" />
At application launch I read an xml file where the background color is saved.
// Some XML Loading stuff -> backgroundColor is a Color
this.Resources["BackgroundColor"] = backgroundColor;
This worked like a charme. I could change the Color in the xml file and the background of my border was whatever color I defined in the xml file.
Actual Problem
Now I moved the definition of the SolidColorBrush and the Color to my App.xaml file and changed the method to change the color to:
Application.Current.Resources["BackgroundColor"] = backgroundColor;
But now the background of the border does not change anymore. It's just the default color of the border. No matter what I write in my xml file.
When I debug what's in
Application.Current.Resources["BackgroundColor"]
the color that was assigned by
Application.Current.Resources["BackgroundColor"] = backgroundColor;
is actually in
Application.Current.Resources["BackgroundColor"]
but the background is not changed...
Background
I have two windows. An main window and a preference window. In the preference window I want to be able to change the FontFamily/Type/Weight/Color etc. of the main window.
My first approach was to define all styles in the main window resources and pass the values I want to change to the preference window and read out the changes and then update the resources in the main window resources.
As this worked very well I now wanted to move the styles to the app.xaml and read and update them there so I don't have to pass them to the preference window and read them from there again.
Can not reproduce. The following code works for me (border shows up as azure):
My one suggestion would be to make sure you removed the resource from the window. The XAML binding would bind to the closest resource which would be the window resource (not the app resource), so you would be binding to the resource you're not changing.
MainWindow.xaml:
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication3="clr-namespace:WpfApplication3"
Title="MainWindow" Height="350" Width="525"
x:Name="Window">
<Window.Resources>
</Window.Resources>
<Grid>
<Border Background="{DynamicResource BackgroundBrush}">
<Button Margin="10">Test</Button>
</Border>
</Grid>
</Window>
App.xaml:
<Application x:Class="WpfApplication3.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<SolidColorBrush x:Key="BackgroundBrush" Color="{DynamicResource BackgroundColor}"/>
<Color x:Key="BackgroundColor">PeachPuff</Color>
</Application.Resources>
</Application>
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Application.Current.Resources["BackgroundColor"] = Colors.Azure;
}
}
Okay I found the solution.
I put the styles into a ResourceDictionary which actually didn't help anything.
BUT:
When I reload the resource dictionary after modifying it the styles get applied.
Actually I thought it would load the dictionary without the changes applied before clearing the merged dictionaries?
Application.Current.Resources["BackgroundColor"] = this.SelectedBackgroundColor;
Application.Current.Resources.MergedDictionaries.Clear();
var dictionary = new ResourceDictionary();
dictionary.Source = new Uri("ControlStyles.xaml", UriKind.Relative);
Application.Current.Resources.MergedDictionaries.Add(dictionary);

Categories

Resources