2013-07-29 23 views
8

Projem, tüm WPF pencereleri için Project aracılığıyla bir ProjectTheme.xaml dosyası kullanıyor.WPF Kaynak dosyasını ve temayı dinamik olarak değiştirin

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <ResourceDictionary.MergedDictionaries> 
     <!-- In order to modify the project's theme, change this line --> 
     <ResourceDictionary Source="/MyProject;component/Themes/WPFThemes/Customized.xaml" /> 
    </ResourceDictionary.MergedDictionaries> 
</ResourceDictionary> 

Tüm WPF, Windows WindowBase.xaml

<Window.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="/MyProject;component/View/WindowBase.xaml"/> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Window.Resources> 

WindowBase.xaml referanslar özelleştirilmiş başlık çubuğu Bar1.xaml

<ResourceDictionary.MergedDictionaries> 
    <ResourceDictionary Source="/MyProject;component/Themes/WPFThemes/Bar1.xaml" /> 
</ResourceDictionary.MergedDictionaries> 

Bar1 başvuran aşağıdaki gibi ProjectTheme.xaml dosyası bir stil tema başvuruyor .xaml başvuruları ProjectTheme.xaml

Yani heriarchy Window1 WindowBase.xaml başvuran

  • olduğunu
  • WindowBase Bar1.xaml başvuran
  • Bar1 ProjectTheme.xaml
  • ProjectTheme.xaml gerçek tema kaynak dosyası başvuru başvuruyor.

Bu iyi çalışıyor. Artık uygulamadan çıkmadan proje temasını dinamik olarak dinamik olarak değiştirmek istiyorum. Birkaç tema tarzı dosyaları

  • Customized.xaml
  • Customized1.xaml
  • Customized2.xaml olduğunu varsayarsak

Sorum şu mümkün dinamik ProjectTheme.xaml dosyasını güncellemek için eğer satırını

numaralı telefondan
<ResourceDictionary Source="/MyProject;component/Themes/WPFThemes/Customized1.xaml" /> 

için

benim hedefe ulaşmak için? Evet ise, nasıl yapabilirim? Hayır ise, amacımın başarılması için neden ve en iyi (diğer) yol nedir?

Aşağıdakileri denedim ama hiçbiri çalışmıyor: stil değişmiyor.

yolu 1

Application.Current.Resources.MergedDictionaries.Clear(); 
Uri NewTheme = new Uri(@"/MyProject;component/Themes/WPFThemes/Customized2.xaml", UriKind.Relative); 
ResourceDictionary dictionary = (ResourceDictionary)Application.LoadComponent(NewTheme); 
Application.Current.Resources.MergedDictionaries.Add(dictionary); 

yolu 2

Application.Current.Resources.MergedDictionaries.RemoveAt(0); 
Uri NewTheme = new Uri(@"/MyProject;component/Themes/WPFThemes/Customized2.xaml", UriKind.Relative); 
ResourceDictionary dictionary = (ResourceDictionary)Application.LoadComponent(NewTheme); 
Application.Current.Resources.MergedDictionaries.Insert(0, dictionary); 

Not: benim gerçek tema tarzı dosyalarında (Customized.xaml ...) Ben dinamik kaynak ve statik kaynağın bir arada kullanılır. Bu önemli mi?

Şimdiden teşekkürler.

cevap

13

Burada dikkate alınacak birkaç şey var.

İlk olarak, StaticResource ile tanımlanan hiçbir şey değişiklik yapılmaz. Temayı çalışma zamanında değiştirmeyi destekleyen bir denetim istiyorsanız, DynamicResource'u kullanmanız gerekir, böylece değişiklikleri aramayı bilir.

Temayı değiştirme konusundaki genel yaklaşımınız doğru. Bunu gerçekleştirmenin en kolay yolu, ResourceDictionary öğenizin App.xaml içinde tanımlandığından emin olarak Application-scoped resource dictionaries kullanıyor. temel sınıflar içindeki kaynakların kullanırken için kendini kafa karıştırıcı olabilir

ResourceDictionary dict = new ResourceDictionary(); 
dict.Source = new Uri("MyResourceDictionary.xaml", UriKind.Relative); 

Application.Current.Resources.MergedDictionaries.Add(dict); 

parçasıdır: yeni bir kaynak eklemek için, aşağıdaki benzer parçacıkları kullandım. Bir kaynağı bir sınıfta tanımladığınızda, kaynak bu türün bir örneğine yerel olur. XAML'nin kendi sınıflarında kendi InitializeComponent() yöntemini derlediğini düşünün, yani orijinal XAML'yi değiştiremez ve değişikliklerin tüm örneklere gitmesini beklemezsiniz. Aynı notta, bir sınıf örneğindeki kaynakların değiştirilmesi diğer örnekleri etkilemez.

Sorunuz gerçekten iki ayrı sorun içeriyor olduğundan (uygulama teması ve denetim kaynaklarını değiştirme), uygulama kaynaklarınızın düzgün şekilde güncelleştirilmesini sağlamaya ve DynamicResource'u kullanmaya odaklanacağım ve umarım ki verdiğim bilgiler nedenini anlamak için yeterli olur. Diğer bazı kaynaklar henüz güncellenmiyor olabilir.

+0

Cevabınız için teşekkürler. Bu neden çalışmadığını açıkladı. Kaynağı, App.xaml dosyasına koydum çünkü projem, bir non -.net programı tarafından çağrılacak bir sınıf kütüphanesi. Bu durumda temayı dinamik olarak değiştirmek hala mümkün mü? – Shawn

+0

Bu mümkün olmalıdır. Ben kendim denemedim, ama diğer bir 'Birleştirilmiş Sözler' içeren kod içinde statik bir 'ResourceDictionary 'tanımlamayı denerim ve çalışıp çalışmadığını görmek için bunu değiştirmeyi denerdim. Baktığım diğer sorulardan yola çıkarak, başkalarının bunu nasıl halledebileceği anlaşılıyor. Http: //stackoverflow.com/questions/3038423/creating-static-resource-dictionary –

+0

Açıklamalarınız bana doğru yönde gelecek mi? . Çok teşekkür ederim. Bunu takdir ediyorum. – Shawn

İlgili konular