Comment définir le style de fenêtre WPF par défaut dans app.xaml?

J’essaie de définir le style par défaut pour chaque fenêtre de mon application Windows WPF dans mon app.xaml. Jusqu’à présent, j’ai ceci dans app.xaml:

       

Je peux faire apparaître la fenêtre avec ce style lors de l’exécution de l’application (mais pas du concepteur VS) en indiquant spécifiquement à la fenêtre d’utiliser ce style via:

 Style="{DynamicResource WindowStyle} 

Cela fonctionne, mais n’est pas idéal. Alors, comment puis-je:

  1. Toutes les fenêtres utilisent-elles automatiquement le style (donc je n’ai pas besoin de le spécifier sur chaque fenêtre)?
  2. Le designer VS a-t-il montré le style?

Merci!

Pour append à ce que Ray dit:

Pour les styles, vous devez soit fournir une clé / ID ou spécifier un type de cible.

Si un FrameworkElement n’a pas de style spécifié explicitement, il recherchera toujours une ressource de style, en utilisant son propre type comme clé.
– Programmation WPF (Sells, Griffith)

Si vous fournissez un TargetType, toutes les instances de ce type auront le style appliqué. Cependant, les types dérivés ne seront pas … il semble.

ne fonctionnera pas pour toutes vos dérivations / fenêtres personnalisées.

s’appliquera uniquement à MyWindow. Donc, les options sont

  • Utilisez un style à clé que vous spécifiez comme propriété de style de chaque fenêtre à laquelle vous souhaitez appliquer le style. Le concepteur montrera la fenêtre stylisée.

.

     ...  ... 
  • Ou vous pouvez dériver d’une classe BaseWindow personnalisée (qui a ses propres particularités ), où vous définissez la propriété Style pendant l’étape Ctor / Initialization / Load. Toutes les dérivés auraient alors automatiquement le style appliqué. Mais le concepteur ne tiendra pas compte de votre style. Vous devez exécuter votre application pour voir le style appliqué. Je suppose que le concepteur exécute simplement InitializeComponent (qui est du code généré automatiquement / par le concepteur) pour que XAML soit appliqué mais pas personnalisé code-behind.

Je dirais donc que les styles explicitement spécifiés sont les moins efficaces. Vous pouvez de toute façon modifier les aspects du style de manière centralisée.

Sachez que ce sont des années plus tard, mais puisque la question est toujours là …

  1. Créez un dictionnaire de ressources dans votre projet (cliquez avec le bouton droit sur le projet …)

    Je vais créer un nouveau dossier sous le projet appelé “Assets” et y mettre “resourceDict.XAML.

  2. Ajoutez le code à resourceDict.XAML:

      
  3. Dans votre fichier Project XAML, ajoutez ce qui suit sous Fenêtre:

              

    réf: le site Web suivant: Problème de référencement d’un dictionnaire de ressources contenant un dictionnaire fusionné “Il y a un bogue: si tous vos styles par défaut sont nesteds dans trois dictionnaires fusionnés profonds ou profonds, le dictionnaire supérieur ne sera pas marqué Le travail consiste à placer un style par défaut sur quelque chose, n’importe quoi, dans le dictionnaire racine. ” Et cela semble réparer les choses de manière fiable. Allez comprendre…

  4. Et enfin, sous Window, peut-être après Title, mais avant la dernière fenêtre ‘>’:

     Style="{DynamicResource windowStyle}" 
  5. Et vous devrez append le code aux étapes 3 et 4 de chaque projet auquel vous souhaitez appliquer le style.

  6. Si vous souhaitez utiliser un arrière-plan dégradé plutôt qu’une couleur unie, ajoutez le code suivant au fichier resourceDict.XAML:

         
  7. Et modifiez votre Style Setter pour la couleur de fond à lire:

      

Les étapes 3 et 4 doivent être répétées dans chaque fichier project.XAML comme décrit ci-dessus, mais bon, vous obtenez un Windows uniforme sur toute la solution! Et le même processus pourrait s’appliquer à tous les contrôles dont vous souhaitez avoir l’aspect uniforme, les boutons, etc.

Pour ceux qui arrivent si tard, j’espère que cela aidera car je suis sûr que les affiches originales ont tout compris depuis des années.

Paul

Le concepteur ne fonctionne pas car vous spécifiez un DynamicResource. S’il vous plaît, changez ceci en StaticResource et tout ira bien.

Pour appliquer à toutes les fenêtres, vous devez supprimer la clé x: du style. Définir le TargetType définit implicitement la clé x: à tout ce qui se trouve dans TargetType. Cependant, dans mes tests, cela ne fonctionne pas, alors je le regarde.

Si je mets le TargetType sur x: Type TextBlock, le concepteur fonctionne parfaitement, il semble juste que la fenêtre affiche un comportement différent.

J’ai enquêté sur celui-ci depuis quelques jours et je l’ai fait fonctionner via le constructeur de ma classe de fenêtres personnalisée:

 public class KWindow : Window { public KWindow() { this.SetResourceReference(StyleProperty, typeof(KWindow)); } static KWindow() { DefaultStyleKeyProperty.OverrideMetadata(typeof(KWindow), new FrameworkPropertyMetadata(typeof(KWindow))); } public override void OnApplyTemplate() { base.OnApplyTemplate(); // gets called finally } } 

J’espère que ça aide quelqu’un

Pour ceux qui ont une solution au problème: Comment puis-je appliquer automatiquement un style personnalisé à tous les types dérivés de Windows? Voici la solution que j’ai trouvée

NOTE: Je ne voulais vraiment pas dériver du type Window ou insérer XAML sur chaque fenêtre pour forcer une mise à jour du style, etc. pour des raisons spécifiques à mon projet (les consommateurs de mon produit utilisent notre bibliothèque de style réutilisable générique et créent leur propre mise en page / fenêtres, etc.) donc j’étais vraiment motivé pour trouver une solution qui fonctionnait que j’étais prêt à vivre avec des effets secondaires

Vous devez parcourir toutes les fenêtres instanciées et les forcer à utiliser le nouveau style personnalisé que vous avez défini pour le type de fenêtre. Cela fonctionne très bien pour les fenêtres déjà installées, mais lorsqu’une fenêtre ou une fenêtre enfant est instanciée, elle ne sait pas utiliser le nouveau type / personnalisé qui a été déclaré pour son type de base. le type de fenêtre vanille. Donc, le mieux que je pouvais trouver était d’utiliser le LostKeyBoardFocus sur la MainWindow pour perdre Focus sur un ChildWindow (IOW Quand une fenêtre enfant a été créée), puis d’appeler ce FixupWindowDerivedTypes ().

Si quelqu’un a une meilleure solution pour “détecter” quand un type quelconque de type dérivé de fenêtre est instancié et appelle donc le FixupWindowDerivedTypes (), ce serait génial. Il peut être utile de gérer le WM_WINDOWPOSCHANGING dans cette zone.

Cette solution n’est donc pas élégante, mais le travail est fait sans que je doive toucher un code ou un fichier XAML lié à mes fenêtres.

  public static void FixupWindowDerivedTypes() { foreach (Window window in Application.Current.Windows) { //May look strange but kindly inform each of your window derived types to actually use the default style for the window type window.SetResourceReference(FrameworkElement.StyleProperty, DefaultStyleKeyResortingever.GetDefaultStyleKey(window)); } } } } //Great little post here from Jafa to resortingeve a protected property like DefaultStyleKey without using reflection. http://themechanicalbride.blogspot.com/2008/11/protected-dependency-properties-are-not.html //Helper class to resortingeve a protected property so we can set it internal class DefaultStyleKeyResortingever : Control { ///  /// This method resortingeves the default style key of a control. ///  /// The control to resortingeve the default style key /// from. /// The default style key of the control. public static object GetDefaultStyleKey(Control control) { return control.GetValue(Control.DefaultStyleKeyProperty); } } 

Vous pouvez append ce code à votre fichier App.xaml.cs:

  FrameworkElement.StyleProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata { DefaultValue = Application.Current.FindResource(typeof(Window)) }); 

Ensuite, le style appliqué au type de Window s’appliquera également à tous les types dérivés de Window

Compte tenu de la réponse de Gishu , j’ai trouvé une autre solution. Mais ça pourrait être un peu bizarre. Si vous utilisez le modèle MVVM, vous pouvez supprimer le code-behind de votre fenêtre et le balisage x: Class dans le fichier XAML. Vous obtiendrez donc une instance de fenêtre ou de votre fenêtre personnalisée, mais pas une instance de classe ‘MainWindow’ dérivée de la classe ‘Window’ et marquée comme étant partielle. Je crée une fenêtre de type VS donc j’ai dû hériter de la classe de fenêtre et étendre sa fonctionnalité. Dans ce cas, il sera possible de rendre la nouvelle classe de fenêtre aussi partielle, ce qui nous permettrait de créer du code sans inheritance.

  1. vous allez enregistrer tous les styles dans un fichier xaml (exemple design.xaml)

  2. puis appelez ce fichier xaml (design.xaml) dans toutes les pages de cette manière

Comme: