Change theme at runtime

前端 未结 5 813
一向
一向 2020-11-30 01:48

I have a WPF application with a theme (ShinyRed.xaml) and I want to have a button that when clicked changes the theme to ShinyBlue.xaml

I load in the theme initially

相关标签:
5条回答
  • 2020-11-30 02:24

    Im using the following command to set the theme at runtime:

    Application.Current.Resources.Source = new Uri("/Themes/ShinyRed.xaml", UriKind.RelativeOrAbsolute);
    
    0 讨论(0)
  • 2020-11-30 02:32

    How you could do it:

    <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 });
        }
    
        //...
    }
    

    In your change method:

    var app = (App)Application.Current;
    app.ChangeTheme(new Uri("New Uri here"));
    
    0 讨论(0)
  • 2020-11-30 02:35

    App.xaml

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

    In your code:

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

    you can check with this to be sure nothing grow

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

    0 讨论(0)
  • 2020-11-30 02:38

    Here is an article that will walk you through it:

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

    Basically you need to remove the "old" theme from the resource dictionary and then merge in the new one. The above article shows you how to make this change very simple.

    0 讨论(0)
  • 2020-11-30 02:44

    H.B.'s answer did not run for me, I had to do this (works, tested):

    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);
    

    To pretty it up:

    // 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));      
    }
    
    0 讨论(0)
提交回复
热议问题