运行期间要改变DynamicResource颜色值 [英] Change DynamicResource Color Value during runtime

查看:132
本文介绍了运行期间要改变DynamicResource颜色值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是在基本主题来定义风格,并且能够通过使用 ResourceDictionary中加载它们对彼此的顶部覆盖在自定义主题的某些价值观。我已经能够得到它的一些性能似乎工作,但没有人因的可冻结对象,颜色是一个不工作。我想改变在ResourceDictionary中的颜色值会工作,但它不是:

My goal is to define style in a Base theme, and be able to override certain values in a Custom theme by loading them on top of each other using ResourceDictionary. I have been able to get it to work with some properties but not others apparently due to Freezable Objects, Colors is one that is not working. I thought changing the Color value in the ResourceDictionary would work but it is not:

MainWindow.xaml:

MainWindow.xaml:

<Grid Background="{DynamicResource PrimaryBackgroundColor}">



Base\Base.xaml:

Base\Base.xaml:

<SolidColorBrush x:Key="PrimaryBackgroundColor" Color="{DynamicResource Color_Base}"/>



Base\Colors.xaml:

Base\Colors.xaml:

<Color x:Key="Color_Base">Red</Color>



Custom\Colors.xaml:

Custom\Colors.xaml:

<Color x:Key="Color_Base">Blue</Color>



Theme.cs:

Theme.cs:

foreach (ResourceDictEntry rde in changeList)
{
    Application.Current.Resources
               .MergedDictionaries
               .ElementAt(rde.dicIndex)[rde.key] = rde.value;
}



中的代码似乎很好地工作,当我通过我看到了MergedDictionary进入步骤为 Color_Base 从红色改为#FFFF0000 #FF0000FF

不过,我的网格,其背景是绑定到DynamicResource PrimaryBackgroundColor 不是从红变蓝

However, my Grid whose Background is bound to the DynamicResource PrimaryBackgroundColor is not being changed from Red to Blue.

有没有在探听显示错误;在Grid.Background值显示PrimaryBackgroundColor为红色(#FFFF0000)。

There are no errors shown in Snoop; the Grid.Background value shows PrimaryBackgroundColor as Red (#FFFF0000).

我在想什么? ?我怎么可以在运行时改变我的颜色值

What am I missing? How can I change my Color value during runtime?

对于这里完整的代码是一个要点:的 https://gist.github.com/dirte/773e6baf9a678e7632e6

编辑:

这看起来是最相关的: http://stackoverflow.com/ A /一百九十九万二千一百九十三分之一千七百七十九万一千七百三十五,但我觉得风格整点是在一个地方来定义它,并拥有一切使用它,而无需修改背后的每一个XAML /代码?什么是最好的解决方案?

This looks to be the most relevant: http://stackoverflow.com/a/17791735/1992193 but I thought the whole point of styles was to define it in one place and have everything use it without having to modify every xaml/code behind? What is the best solution?

我知道一个解决方案是简单地将整个基本主题复制到自定义主题,只加载哪些主题,你想要的,但它需要每一个跨越每一个主题的文件,该文件是不希望被托管属性。

I know one solution is to simply copy the entire base theme into a custom theme and only load which theme you want, but then it requires every property being managed across every theme file which is undesired.

推荐答案

我能够通过简单地将所有的资源,以制定出一个解决方案字典文件转换成代码和应用最终的合并资源字典单一的资源字典。

I was able to work out a solution by simply combining all the resource dictionary files into a single resource dictionary in code and applying the final combined resource dictionary.

public static void ChangeTheme(string themeName)
{
    string desiredTheme = themeName;    
    Uri uri;
    ResourceDictionary resourceDict;
    ResourceDictionary finalDict = new ResourceDictionary();

    // Clear then load Base theme
    Application.Current.Resources.MergedDictionaries.Clear();
    themeName = "Base";
    foreach (var themeFile in Util.GetDirectoryInfo(Path.Combine(ThemeFolder, themeName)).GetFiles())
    {
        uri = new Uri(Util.GetPath(Path.Combine(ThemeFolder, themeName + @"\" + themeFile.Name)));
        resourceDict = new ResourceDictionary { Source = uri };
        foreach (DictionaryEntry de in resourceDict)
        {
            finalDict.Add(de.Key, de.Value);
        }
    }
    // If all you want is Base, we are done
    if (desiredTheme == "Base")
    {
        Application.Current.Resources.MergedDictionaries.Add(finalDict);
        return;
    }

    // Now load desired custom theme, replacing keys found in Base theme with new values, and adding new key/values that didn't exist before
    themeName = desiredTheme;
    bool found;
    foreach (var themeFile in Util.GetDirectoryInfo(Path.Combine(ThemeFolder, themeName)).GetFiles())
    {
        uri = new Uri(Util.GetPath(Path.Combine(ThemeFolder, themeName + @"\" + themeFile.Name)));
        resourceDict = new ResourceDictionary { Source = uri };
        foreach (DictionaryEntry x in resourceDict)
        {
            found = false;
            // Replace existing values
            foreach (DictionaryEntry z in finalDict)
            {
                if (x.Key.ToString() == z.Key.ToString())
                {
                    finalDict[x.Key] = x.Value;
                    found = true;
                    break;
                }
            }

            // Otherwise add new values
            if (!found)
            {
                finalDict.Add(x.Key, x.Value);
            }
        }
    }

    // Apply final dictionary
    Application.Current.Resources.MergedDictionaries.Add(finalDict);
}



MainWindow.xaml:

MainWindow.xaml:

<Grid Background="{DynamicResource PrimaryBackgroundColor}">



Base.xaml:

Base.xaml:

<SolidColorBrush x:Key="PrimaryBackgroundColor" Color="{DynamicResource Color_Base}"/>



Base\Colors.xaml:

Base\Colors.xaml:

<Color x:Key="Color_Base">Red</Color>



Custom\Colors.xaml:

Custom\Colors.xaml:

<Color x:Key="Color_Base">Blue</Color>

这篇关于运行期间要改变DynamicResource颜色值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆