Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
250
Changing Theme colors
posted

Hi all!

What I'm trying to achieve is to change 2 colors in the theme (accent colors basically) keeping everything else same as it comes out of the box.

What I don't want to do is to copy the default styles in my project, mainly because I'd like to be always up to date with the latest changes coming in the new versions/SRs and I don't want my code blown up with hundreds of lines of those styles just because I want to change 2 colors.

My current approach is changing the resources in the resource dictionaries of the original theme and registering a new theme at runtime at an early startup. The code is as following:

private static void CreateCustomMetroTheme(IEnumerable<Type> controlTypes, ResourceDictionary myColors)
{
    var accentColorKey = "Color_024";
    var metroDictionary = ThemeManager.GetResourceSet("Metro", ThemeManager.AllGroupingsLiteral);
    var accentColor = (Color)metroDictionary[accentColorKey];
    var newAccentColor = (Color)myColors["AccentColor"];
    ChangeColor(metroDictionary, accentColor, newAccentColor);
    metroDictionary[accentColorKey] = newAccentColor;
    foreach (var controlType in controlTypes)
    {
        foreach (var grouping in ThemeManager.GetGroupingsForType(controlType))
        {
            ThemeManager.Register("CustomMetro", grouping, metroDictionary);
        }
    }
}

private static void ChangeColor(ResourceDictionary dictionary, Color oldColor, Color newColor)
{
    foreach (var key in dictionary.Keys)
    {
        if (dictionary[key] is SolidColorBrush brush && brush.Color == oldColor)
        {
            dictionary[key] = new SolidColorBrush(newColor);
        }
    }
    foreach (var mergedDictionary in dictionary.MergedDictionaries)
    {
        ChangeColor(mergedDictionary, oldColor, newColor);
    }
}

This works pretty well for most of the stuff, I'm testing on a XamDataGrid: the group by box, group by prompt, group by plus/minus icons in a pressed state, DateTimeField editor - all this is correctly displayed with the new color (in my case kind of dark blue). The only problem I found so far is the scrollbar. For some reason, the Thumb in a pressed state is still displayed with the old color, see the picture below:

Do you have any idea why the scrollbar doesn't get the new brush (I guess it might be smth to do with how the triggers are working with the resources in WPF)? Can you think of any possible workaround for this issue? Or maybe there is some alternative approach in order to change all the usages of the accent color in a metro theme with relatively few lines of code?

Thanks in advance!