WPF样式/主题:占位符

时间:2015-05-21 06:52:23

标签: c# wpf xaml styles themes

我有一个WPF项目,有2个主题,黑暗和光明。 主题放在我的调试中的单独文件夹中。

DarkTheme.xaml

<Style x:Key="Handle" TargetType="Grid">
    <Setter Property="OverridesDefaultStyle" Value="True" />
    <Setter Property="Background" Value="#FF323232" />
</Style>

<Style x:Key="Label" TargetType="Label">
    <Setter Property="Foreground" Value="#FFC8C8C8" />
</Style>

LightTheme.xaml

<Style x:Key="Handle" TargetType="Grid">
    <Setter Property="OverridesDefaultStyle" Value="True" />
    <Setter Property="Background" Value="#FFFAFAFA" />
</Style>

<Style x:Key="Label" TargetType="Label">
    <Setter Property="Foreground" Value="#FF323232" />
</Style>

然后我将主题应用于标签作为DynamicResource

<Label Content="TestLabel" Style="{DynamicResource Label}" Foreground="#FF323232"/>

这就是我如何加载它们

private void ThemeChanged(object sender, SelectionChangedEventArgs e)
    {
        if (combo.SelectedIndex == -1) return;

        foreach (var command in Directory.GetFiles(((ThemeData)combo.SelectedValue).ThemePath).Where(x => x.EndsWith(".xaml")))
        {
            var stream = new FileStream(command, FileMode.Open);

            foreach (DictionaryEntry dictionaryEntry in (ResourceDictionary)XamlReader.Load(stream))
            {
                Application.Current.Resources[dictionaryEntry.Key] = dictionaryEntry.Value;
            }
        }
    }

问题

标签前景在更改主题(运行时)时不会更改,除非我将Foreground保留为null。但我不能在设计中留下一切空白(因为我无法使用空白屏幕)

那么如何让主题覆盖样式呢?或者也许我可以制作占位符样式?

1 个答案:

答案 0 :(得分:1)

I don't know what you are doing to load the theme resources, but what you need to do is unload the previous theme (remove it from the application resources) then load the new theme. If you have them both loaded into the resources at the same time, there is no way for controls to determine which one to apply.

Edit: Since you are merging the keys into the application resources and then replacing them when the theme changes (and that is not working), then changing the value of an existing resource must not be enough to trigger an update.

In my own personal WPF theme library, when I load a theme, I take the dictionary generated by the theme and add it to the application's Resources.MergedDictionaries collection. I also keep a reference to the dictionary so that when I later unload the theme, I can remove it from the merged dictionaries collection. Doing it this way ensures that all of the theme resources are completely unloaded. You may want to consider doing something similar.

P.S. You are creating a file stream and never closing it. That will result in that file being inaccessible until the application is closed. You should wrap that block of code in a using statement.