WPF modifier Dynamiquement fichier de ressources et de thème
Mon projet utilise un ProjectTheme.fichier xaml pour tous WPF, windows par le biais de son projet.
Le ProjectTheme.fichier xaml fait référence à un thème de style comme suit
<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>
Tous WPF, Windows références WindowBase.xaml
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/MyProject;component/View/WindowBase.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
WindowBase.xaml références personnalisées barre de titre Bar1.xaml
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/MyProject;component/Themes/WPFThemes/Bar1.xaml" />
</ResourceDictionary.MergedDictionaries>
Bar1.xaml références ProjectTheme.xaml
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/MyProject;component/ProjectTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>
De sorte que le heriarchy est
- Window1 références WindowBase.xaml
- WindowBase références Bar1.xaml
- Bar1 références ProjectTheme.xaml
- ProjectTheme.xaml de référence le véritable thème de fichier de ressources.
Cela fonctionne bien.
Maintenant, j'ai envie de changer dynamiquement le thème du projet au moment de l'exécution, sans quitter l'application.
En supposant que j'ai plusieurs thème des fichiers de style
- Personnalisés.xaml
- Customized1.xaml
- Customized2.xaml
Ma question est
s'il est possible de mettre à jour dynamiquement les ProjectTheme.fichier xaml au moment de l'exécution de changer la ligne
de
<ResourceDictionary Source="/MyProject;component/Themes/WPFThemes/Customized.xaml" />
à
<ResourceDictionary Source="/MyProject;component/Themes/WPFThemes/Customized1.xaml" />
pour atteindre mon objectif?
Si oui, comment dois-je faire?
Si non, quelle est la raison et quel est le meilleur (d'autres) de manière à atteindre mon but?
J'ai essayé ce qui suit, mais aucune de ces travaux: le style ne change pas.
voie 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);
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);
Note:
Dans ma vraie thème des fichiers de style (sur mesure.xaml...), j'ai utilisé une combinaison de ressource dynamique et statique de la ressource. N'a que des questions?
Merci d'avance.
OriginalL'auteur Shawn | 2013-07-29
Vous devez vous connecter pour publier un commentaire.
Il ya quelques choses à considérer ici.
Tout d'abord, quelque chose de défini avec
StaticResource
ne sera pas mis à jour sur un changement. Si vous voulez un contrôle à l'appui de la modification du thème lors de l'exécution, vous devez utiliserDynamicResource
de sorte qu'il sait de surveiller les changements.Votre approche globale de changer le thème est correct. La meilleure façon d'y parvenir est d'utiliser Application étendue des dictionnaires de ressources, assurez-vous que votre
ResourceDictionary
est défini dans votreApp.xaml
. Pour ajouter une nouvelle ressource, j'ai utilisé des extraits de code semblable au suivant:La partie que vous avez peut être source de confusion-vous plus lors de l'utilisation des ressources au sein des classes de base. Lorsque vous définissez une ressource dans une classe, la ressource locale à une instance de ce type. Penser le code XAML de la compilation dans son propre
InitializeComponent()
méthode sur les classes, ce qui signifie que vous ne pouvez pas modifier l'original XAML et s'attendre à des changements pour aller à toutes les instances. Sur la même note, en changeant les ressources sur une instance de classe n'a pas d'effet d'autres instances.Depuis votre question contient en réalité deux préoccupations distinctes (application de la thématisation et de changement de contrôle des ressources), je tiens à assurer les ressources de votre application sont à jour correctement et en utilisant
DynamicResource
, et nous espérons que les informations que j'ai fourni serait suffisant pour comprendre pourquoi certaines autres ressources ne peuvent pas être mise à jour encore.Il doit être possible. Je n'ai pas essayé moi-même, mais je préfère expérimenter avec la définition d'une statique
ResourceDictionary
dans le code, contenant vos autresMergedDictionaries
, et d'essayer de changer cela, pour voir si cela fonctionne. À en juger par d'autres questions que j'ai regardé, il semble que peut-être la façon dont les autres les gérer.stackoverflow.com/questions/3038423/...Va, ton explication me mettre dans la bonne direction. Je vous remercie beaucoup. Je l'apprécie.
Sur
DynamicResource
. Comment faire lorsque vous définissez les couleurs dans convertisseurs?<conv:RejectedOrMissedCallColorConverter x:Key="RejectedOrMissedCallColorConverter" MatchColor="Red" DefaultColor="{StaticResource BlackColorBrush}"/>
. Je ne peux pas utiliser dynamique ici...OriginalL'auteur Will Eddins