2013-10-17 1 views
0

목표는 기본 테마에서 스타일을 정의하고 사용자 정의 테마의 특정 값을 ResourceDictionary을 사용하여 위에 겹쳐서 덮어 쓸 수있게하는 것입니다. 나는 어떤 속성을 가지고 작동하도록 만들었지 만, 다른 것들은 분명히 Freezable Objects으로 인해 얻을 수 없었습니다. 색상은 작동하지 않습니다. 나는 일 것 ResourceDictionary의의 색상 값을 변경 생각하지만 그렇지 않다 :런타임 동안 DynamicResource 색상 값을 변경하십시오.

MainWindow.xaml :

<Grid Background="{DynamicResource PrimaryBackgroundColor}"> 

자료 \ Base.xaml :

<SolidColorBrush x:Key="PrimaryBackgroundColor" Color="{DynamicResource Color_Base}"/> 

자료 \ Colors.xaml :

<Color x:Key="Color_Base">Red</Color> 

사용자 \ Colors.xaml :

<Color x:Key="Color_Base">Blue</Color> 

Theme.cs :

foreach (ResourceDictEntry rde in changeList) 
{ 
    Application.Current.Resources 
       .MergedDictionaries 
       .ElementAt(rde.dicIndex)[rde.key] = rde.value; 
} 

코드는 내가 블루 #FF0000FF에 레드 #FFFF0000에서 변경할 수 내가 Color_Base에 대한 MergedDictionary 항목을보고하고 단계별 때 잘 작동이 나타납니다.

그러나 배경이 DynamicResource PrimaryBackgroundColor에 바인딩 된 내 그리드가 빨간색에서 파란색으로 변경되지 않습니다.

스눕에는 오류가 표시되지 않습니다. Grid.Background 값은 PrimaryBackgroundColor를 빨간색으로 표시합니다 (# FFFF0000).

무엇이 누락 되었습니까? 런타임 중에 색상 값을 변경하려면 어떻게해야합니까? https://gist.github.com/dirte/773e6baf9a678e7632e6

편집이 :

이 가장 관련성이 보인다 : 여기에 전체 코드에 대한

가 요점이다 https://stackoverflow.com/a/17791735/1992193을하지만 스타일의 전체 지점 한 곳에서 그것을 정의라고 생각하고 모든 xaml/코드를 수정하지 않고도 모든 것을 사용할 수 있습니까? 가장 좋은 솔루션은 무엇입니까?

기본 테마 전체를 사용자 정의 테마로 복사하고 원하는 테마 만로드하는 것이 좋지만 모든 테마 파일에서 원하지 않는 모든 속성을 관리해야합니다.

답변

2

코드에서 모든 리소스 사전 파일을 단일 리소스 사전에 결합하고 최종 결합 된 리소스 사전을 적용하여 솔루션을 완성 할 수있었습니다.

public static void ChangeTheme(string themeName) 
{ 
    string desiredTheme = themeName;  
    Uri uri; 
    ResourceDictionary resourceDict; 
    ResourceDictionary finalDict = new ResourceDictionary(); 

    // Clear then load Base theme 
    Application.Current.Resources.MergedDictionaries.Clear(); 
    themeName = "Base"; 
    foreach (var themeFile in Util.GetDirectoryInfo(Path.Combine(ThemeFolder, themeName)).GetFiles()) 
    { 
     uri = new Uri(Util.GetPath(Path.Combine(ThemeFolder, themeName + @"\" + themeFile.Name))); 
     resourceDict = new ResourceDictionary { Source = uri }; 
     foreach (DictionaryEntry de in resourceDict) 
     { 
      finalDict.Add(de.Key, de.Value); 
     } 
    } 
    // If all you want is Base, we are done 
    if (desiredTheme == "Base") 
    { 
     Application.Current.Resources.MergedDictionaries.Add(finalDict); 
     return; 
    } 

    // Now load desired custom theme, replacing keys found in Base theme with new values, and adding new key/values that didn't exist before 
    themeName = desiredTheme; 
    bool found; 
    foreach (var themeFile in Util.GetDirectoryInfo(Path.Combine(ThemeFolder, themeName)).GetFiles()) 
    { 
     uri = new Uri(Util.GetPath(Path.Combine(ThemeFolder, themeName + @"\" + themeFile.Name))); 
     resourceDict = new ResourceDictionary { Source = uri }; 
     foreach (DictionaryEntry x in resourceDict) 
     { 
      found = false; 
      // Replace existing values 
      foreach (DictionaryEntry z in finalDict) 
      { 
       if (x.Key.ToString() == z.Key.ToString()) 
       { 
        finalDict[x.Key] = x.Value; 
        found = true; 
        break; 
       } 
      } 

      // Otherwise add new values 
      if (!found) 
      { 
       finalDict.Add(x.Key, x.Value); 
      } 
     } 
    } 

    // Apply final dictionary 
    Application.Current.Resources.MergedDictionaries.Add(finalDict); 
} 

MainWindow.xaml :

<Grid Background="{DynamicResource PrimaryBackgroundColor}"> 

Base.xaml :

<SolidColorBrush x:Key="PrimaryBackgroundColor" Color="{DynamicResource Color_Base}"/> 

자료 \ Colors.xaml :

<Color x:Key="Color_Base">Red</Color> 

사용자 \ 색상입니다.xaml :

<Color x:Key="Color_Base">Blue</Color> 
관련 문제