12

WPF 允许控件库为不同的系统主题提供不同的资源字典,本质上允许应用程序匹配操作系统选择的视觉主题(Aero、Luna 等)。

我想知道是否可以在我的应用程序中包含多个主题资源字典并在框架内利用一些现有的主题支持。这应该适用于我自己的主题名称,并且理想情况下允许用户更改主题,从而在运行时更改应用程序的皮肤外观。即使这只是一个配置设置,它仍然可能很有趣。

4

2 回答 2

14

这是我在支持主题的应用程序中使用的代码片段。在此示例中,我有两个主题(默认和经典 XP)。主题资源分别存储在 DefaultTheme.xaml 和 ClassicTheme.xaml 中。

这是我的 App.xaml 中的默认代码

<Application ...>
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="ArtworkResources.xaml" />
                <ResourceDictionary Source="DefaultTheme.xaml" />
            </ResourceDictionary.MergedDictionaries>

            <Style x:Key="SwooshButton" TargetType="ButtonBase">
                <!-- style setters -->
            </Style>

            <!-- more global styles -->
        </ResourceDictionary>
    </Application.Resources>
</Application>

然后在 App.xaml 后面的代码中,我有以下方法来允许更改主题。基本上,您所做的是清除资源字典,然后使用新主题重新加载字典。

    private Themes _currentTheme = Themes.Default;
    public Themes CurrentTheme
    {
        get { return _currentTheme; }
        set { _currentTheme = value; }
    }

    public void ChangeTheme(Themes theme)
    {
        if (theme != _currentTheme)
        {
            _currentTheme = theme;
            switch (theme)
            {
                default:
                case Themes.Default:
                    this.Resources.MergedDictionaries.Clear();
                    AddResourceDictionary("ArtworkResources.xaml");
                    AddResourceDictionary("DefaultTheme.xaml");
                    break;
                case Themes.Classic:
                    this.Resources.MergedDictionaries.Clear();
                    AddResourceDictionary("ArtworkResources.xaml");
                    AddResourceDictionary("ClassicTheme.xaml");
                    break;
            }
        }
    }

    void AddResourceDictionary(string source)
    {
        ResourceDictionary resourceDictionary = Application.LoadComponent(new Uri(source, UriKind.Relative)) as ResourceDictionary;
        this.Resources.MergedDictionaries.Add(resourceDictionary);
    }

使用这种方法您还需要记住的是,任何使用主题的样式都需要具有动态资源。例如:

<Window Background="{DynamicResource AppBackgroundColor}" />
于 2009-05-10T03:50:59.953 回答
3

我不知道在框架中执行此操作的方法,但是如果您设置可以更改自己的每个控件的样式,您就可以做到。

原理是制作样式a DynamicResource,然后ResourcesDictionary根据用户配置加载不同样式的样式。

是一篇有示例的文章。

于 2009-05-10T01:18:46.107 回答