在运行时更改主题

时间:2011-06-03 16:08:18

标签: wpf

我有一个带主题的WPF应用程序(ShinyRed.xaml),我希望有一个按钮,点击后将主题更改为ShinyBlue.xaml

我最初在App.xaml中加载主题:

<Application.Resources>
    <ResourceDictionary Source="/Themes/ShinyBlue.xaml"/>
</Application.Resources>

我该怎么做?

5 个答案:

答案 0 :(得分:30)

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary x:Name="ThemeDictionary">
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="/Themes/ShinyRed.xaml"/>
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
    <!-- ... -->
public partial class App : Application
{
    public ResourceDictionary ThemeDictionary
    {
        // You could probably get it via its name with some query logic as well.
        get { return Resources.MergedDictionaries[0]; }
    }

    public void ChangeTheme(Uri uri)
    {
        ThemeDictionary.MergedDictionaries.Clear();
        ThemeDictionary.MergedDictionaries.Add(new ResourceDictionary() { Source = uri });
    }

    //...
}

在您的更改方法中:

var app = (App)Application.Current;
app.ChangeTheme(new Uri("New Uri here"));

答案 1 :(得分:7)

这篇文章将引导您完成它:

http://svetoslavsavov.blogspot.com/2009/07/switching-wpf-interface-themes-at.html

基本上你需要从资源字典中删除“旧”主题,然后合并到新主题中。上面的文章向您展示了如何使这一变化变得非常简单。

答案 2 :(得分:6)

我使用以下命令在运行时设置主题:

Application.Current.Resources.Source = new Uri("/Themes/ShinyRed.xaml", UriKind.RelativeOrAbsolute);

答案 3 :(得分:4)

的App.xaml

    <Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Themes/Font.xaml" />
            <ResourceDictionary Source="Themes/Light.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

在您的代码中:

> Application.Current.Resources.MergedDictionaries[1].Source = new Uri("Themes/Dark.xaml", UriKind.RelativeOrAbsolute);

你可以检查这一点,以确保没有增长

Application.Current.Resources.MergedDictionaries.Count.ToString();

答案 4 :(得分:2)

H.B.的回答没有针对我,我必须这样做(工作,测试):

Uri dictUri = new Uri(@"/Resources/Themes/MyTheme.xaml", UriKind.Relative);
ResourceDictionary resourceDict = Application.LoadComponent(dictUri) as ResourceDictionary;
Application.Current.Resources.MergedDictionaries.Clear();
Application.Current.Resources.MergedDictionaries.Add(resourceDict);

要搞清楚:

// Place in App.xaml.cs
public void ChangeTheme(Uri uri)
{
    ResourceDictionary resourceDict = Application.LoadComponent(uri) as ResourceDictionary;
    Application.Current.Resources.MergedDictionaries.Clear();
    Application.Current.Resources.MergedDictionaries.Add(resourceDict);
}

// Example Usage (anywhere in app)
private void ThemeRed_Click(object sender, RoutedEventArgs e)
{
    var app = App.Current as App;
    app.ChangeTheme(new Uri(@"/Resources/Themes/RedTheme.xaml", UriKind.Relative));      
}