2009-05-10 7 views
10

WPF를 사용하면 컨트롤 라이브러리가 서로 다른 시스템 사전에 서로 다른 리소스 사전을 제공 할 수 있으므로 응용 프로그램이 운영 체제의 선택한 시각적 테마 (Aero, Luna 등)와 일치 할 수 있습니다.WPF 테마를 사용하여 런타임에 변경할 수있는 응용 프로그램의 여러 스킨을 포함 할 수 있습니까?

내 응용 프로그램에 여러 테마 리소스 사전을 포함시키고 프레임 워크 내에서 기존 테마 지원을 활용할 수 있는지 궁금합니다. 이것은 내 자신의 테마 이름을 위해 작동해야하며, 이상적으로 사용자가 테마를 변경할 수 있도록 허용하고 런타임시 응용 프로그램의 스킨 된 모양을 변경할 수 있도록합니다. 이것이 단지 구성 설정 일지라도 여전히 흥미로울 수 있습니다.

답변

11

다음은 테마를 지원하는 애플리케이션에서 사용한 코드 스 니펫입니다. 이 예제에서는 두 가지 테마 (기본 및 클래식 XP)가 있습니다. 테마 리소스는 각각 DefaultTheme.xaml 및 ClassicTheme.xaml에 저장됩니다.

내가 테마를 변경할 수 있도록하기 위해 다음과 같은 방법을 가지고있는 App.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> 

의 기본 코드입니다. 기본적으로, 당신은 리소스 사전을 지운 다음 새 테마로 사전을 다시로드합니다.

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}" /> 
+0

위의 대답을 구현 한 결과, 바운드 버튼 이미지를 변경하는 방법을 궁금합니다. 나는 여기에 질문을했습니다 : http://stackoverflow.com/questions/39795317/how-do-i-dynamically-change-which-resource-folder-i-get-an-image-from – AidanO

3

프레임 워크에서이 작업을 수행하는 방법을 모르지만 자신을 변경할 수있는 모든 컨트롤의 스타일을 지정할 수 있습니다.

이론은 DynamicResource 스타일을 만들고 다른 스타일의 사용자 구성을 기반으로 ResourcesDictionary을로드하는 것입니다.

Here은 예제가있는 기사입니다.