在WPF中更改主题,主题不变

时间:2019-11-23 19:42:15

标签: c# wpf

这只是POC的草稿!

The Dictionary hierarchy is;
  Colors
  Brushes
  Styles

So the ordering is important

我正在尝试在WPF中更改主题,我可以这样做;

+        private void ChangeTheme(string themeName)
+        {
+            ResourceDictionary resource = null;
+            using (FileStream fs = new FileStream("../../../Resources/ResourceDictionaries/" + themeName + ".xaml", FileMode.Open, FileAccess.Read))
+                resource = (ResourceDictionary)XamlReader.Load(fs);
+
+            Application.Current.Resources.MergedDictionaries.Clear();
+            Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary()
+            { Source = new Uri("pack://application:,,,/Resources/ResourceDictionaries/dictionary1.xaml") });
+            Application.Current.Resources.MergedDictionaries.Add(resource);
+            Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary()
+            { Source = new Uri("pack://application:,,,/Resources/ResourceDictionaries/Monotone.Brushes.xaml") });
+            Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary()
+            { Source = new Uri("pack://application:,,,/Resources/ResourceDictionaries/Monotone.xaml") });
+        }

但是,如果我向项目添加更多ResourceDictionaries,则必须回到这里并修改列表。

所以我想我会这样做,但似乎不起作用。主题不变!新主题被加载,旧字典被转移到dictionaryCollection,所有内容都被添加回Application.Current.Resources.MergedDictionariy,但是新主题没有显示?

我已经在Google上搜索了两个小时,发现的所有内容都说这应该可行?

private void ChangeTheme(string themeName)
{
    ResourceDictionary resource = null;
    string file = "../../../Resources/ResourceDictionaries/" + themeName + ".xaml";
    //using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
    //    resource = (ResourceDictionary)XamlReader.Load(fs);

    resource = new ResourceDictionary();
    resource.Source = new Uri(file, UriKind.Relative);

    ResourceDictionary rd = GetActualResourceDictionary();
    if (rd != null)
        Application.Current.Resources.MergedDictionaries.Remove(rd);

    // Create collection to hold old RecourceDictionaries
    System.Collections.ObjectModel.Collection<ResourceDictionary> dictionaryCollection = new
        System.Collections.ObjectModel.Collection<ResourceDictionary>();

    // Copy REsourceDictionaries left after removing the Theme
    foreach (ResourceDictionary dict in Application.Current.Resources.MergedDictionaries)
        dictionaryCollection.Add(dict);

    Application.Current.Resources.MergedDictionaries.Clear();
    Application.Current.Resources.MergedDictionaries.Add(resource);

    foreach (ResourceDictionary dict in dictionaryCollection)
        Application.Current.Resources.MergedDictionaries.Add(dict);
}

//NOTE This works but the
static ResourceDictionary GetActualResourceDictionary()
{
    // get the actual ResourceDictionary
    foreach (ResourceDictionary res in Application.Current.Resources.MergedDictionaries)
    {
        if (res.Source != null)
        {
            string source = res.Source.ToString();
            if (source.ToUpper().Contains("THEME"))
                return res;
        }
    }
    return null;
}

1 个答案:

答案 0 :(得分:0)

在这里,我错过了一件重要的事情;我实际上如何在XAML中使用样式。主题只有在是DynamicResource时才能够更改资源,因此无论我对资源字典做什么,任何StaticResource条目都将保持其原始样式。