Is your feature request related to a problem? Please describe.
I want one of my controls background to have the Accent brush. If I used the static resource way, the control will not change its background color if I changed the application accent at runtime. We need a way to create Binding to the color I need.
Describe the solution you'd like
First step of solution is to create a helper class with properties of the colors and brushes of both the theme and accent, and implement INotifyPropertyChanged interface.... Now we can create this helper class in the App resource and bind our control's property to its properties, and they will change there colors if I changed the theme and accent at runtime.... The helper class code may look like this:
``` C#
using System;
using System.Collections.Generic;
using System.Linq;
using MahApps.Metro;
using System.Windows.Media;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace CM
{
public class ThemeChange : INotifyPropertyChanged
{
#region Theme Change
List
private void ThemeChanged(object sender, OnThemeChangedEventArgs e)
{
if (properties == null) properties = GetType().GetProperties().Select(p => p.Name).ToList();
foreach (var item in properties)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(item));
}
}
#endregion
public ThemeChange()
{
ThemeManager.IsThemeChanged += ThemeChanged;
}
#region Accent Properties
Accent GetAccent()
{
var a = ThemeManager.DetectAppStyle()?.Item2;
if (a == null) a = ThemeManager.GetAccent("Cyan");
return a;
}
T GetItem
public event PropertyChangedEventHandler PropertyChanged;
public Brush AccentColorBrush => GetItem
public Brush AccentColorBrush2 => GetItem
public Brush AccentColorBrush3 => GetItem
public Brush AccentColorBrush4 => GetItem
public Brush AccentBaseColorBrush => GetItem
public Brush WindowTitleColorBrush => GetItem
public Brush IdealForegroundColorBrush => GetItem
public Brush IdealForegroundDisabledBrush => GetItem
public Brush AccentSelectedColorBrush => GetItem
#endregion
#region Theme Properties
AppTheme GetTheme()
{
var a = ThemeManager.DetectAppStyle()?.Item1;
if (a == null) a = ThemeManager.GetAppTheme("BaseLight");
return a;
}
T GetThemeItem
public Brush ControlBackgroundBrush => GetThemeItem
public Brush WhiteBrush => GetThemeItem
#endregion
}
}
Second step to make life easier is to create a MarkupExtension To use it directly in our code without the need to create a helper object in the App Resource. The MarkupExtension code may looks like this:
``` C#
using System;
using System.Windows.Data;
using System.Windows.Markup;
namespace CM
{
public enum ThemeElement
{
AccentColorBrush,
AccentColorBrush2,
AccentColorBrush3,
AccentColorBrush4,
AccentBaseColorBrush,
WindowTitleColorBrush,
IdealForegroundColorBrush,
IdealForegroundDisabledBrush,
AccentSelectedColorBrush,
ControlBackgroundBrush,
WhiteBrush
}
public class ThemeBinding : MarkupExtension
{
static ThemeChange themeChange = new ThemeChange();
public ThemeElement Element { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
var binding = new Binding(Enum.GetName(typeof(ThemeElement), Element)) { Source = themeChange, Mode = BindingMode.OneWay };
var expression = binding.ProvideValue(serviceProvider);
return expression;
}
}
}
And we can use it in our code like this:
<Grid Background="{cm:ThemeBinding Element=AccentColorBrush}">
.
.
.
</Grid>
Additional context
Closed Issues
If I used the static resource way, the control will not change its background color if I changed the application accent at runtime.
Why are you using StaticResource instead of DynamicResource if you want dynamic changes?
You are right in that point.... DynamicResource will solve the problem.....
However, the binding way can give auto complete in xaml editor.... If you are working on that in another way it would be not necessary also.
Best Regards
Most helpful comment
Why are you using
StaticResourceinstead ofDynamicResourceif you want dynamic changes?