How to set WPF Window Style in app.xaml?

I am trying to set the default style for each window in a WPF Windows application in my app.xaml application. So far I have this in app.xaml:

<Application.Resources> <ResourceDictionary> <Style x:Key="WindowStyle" TargetType="{x:Type Window}"> <Setter Property="Background" Value="Blue" /> </Style> </ResourceDictionary> </Application.Resources> 

I can make the window appear with this style when the application starts (but is not a VS designer) by specifically specifying the window to use this style with:

 Style="{DynamicResource WindowStyle} 

It works, but not perfect. So how am I:

  • Do all windows automatically use a style (so I don’t need to specify it in every window)?
  • Ask designer VS to show style?

Thank!

+58
styles wpf themes
Jan 10 '09 at 23:11
source share
8 answers

To add to what Ray says:

For styles, you need to specify a key / identifier or specify TargetType.

If the FrameworkElement element does not have an explicitly specified style, it will always look for the style resource using its own type as the key.
- WPF programming (Sells, Griffith)

If you specify TargetType, all instances of this type will apply the style. However, derived types will not ... seem. <Style TargetType="{x:Type Window}"> will not work for all your custom derivations / windows. <Style TargetType="{x:Type local:MyWindow}"> will only apply to MyWindow. Thus, the parameters

  • Use the Keyed style that you specify as the Style property in each window that you want to apply to the style. The designer will show a stylized window.

.

  <Application.Resources> <Style x:Key="MyWindowStyle"> <Setter Property="Control.Background" Value="PaleGreen"/> <Setter Property="Window.Title" Value="Styled Window"/> </Style> </Application.Resources> ... <Window x:Class="MyNS.MyWindow" Style="{StaticResource MyWindowStyleKey}"> ... 
  • Or you could get from the custom BaseWindow class (which has its own quirks ), where you set the Style property during Ctor / Initialization / Download once. Then all derivatives will automatically apply the style. But the designer will not pay attention to your style. . You need to run the application to see the applied style. I assume that the designer simply runs the InitializeComponent (which is the code generated automatically / by the constructor) so XAML is applied but not configured based on the code.

So, I would say that explicitly specified styles are the least effective. In any case, you can change the style aspects in the center.

+46
Jan 20 '09 at 10:34
source share

Know this for many years, but since the question is still here ...

  • Create a resource dictionary in your project (right click on the project ...)

    I will create a new folder in the project called "Assets" and put in it "resourceDict.XAML".

  • Add the code to resourceDict.XAML:

     <Style x:Key="WindowStyle" Target Type="Window" > <Setter Property="Background" Value="Blue" /> </Style> 
  • In the Project XAML file, add the following under the window:

     <Window.Resources> <ResourceDictionary> <!-- Believe it or not the next line fixes a bug MS acknowledges --> <Style TargetType="{x:Type Rectangle}" /> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="/Assets/resourceDict.XAML" /> </ResourceDictionary.MergedDictionaries> <ResourceDictionary> </Window.Resources> 

    link to the following website: There is a problem with a link to a resource dictionary that contains a federated dictionary "There is a mistake: if all your styles are nested by default in the integrated dictionaries three levels deep (or deeper), the top dictionary does not get marked, so the search skips its. The work around is to put the default style in something, anything, in the root dictionary. " And that seems to secure things. Go figure ...

  • And finally, under the window, possibly after the Title, but before the final Window '>':

     Style="{DynamicResource windowStyle}" 
  • And you need to add the code in steps 3 and 4 to each project to which you want to apply a style.

  • If you want to use a gradient background rather than a solid color, add the following code to resourceDict.XAML:

     <LinearGradientBrush x:Key="windowGradientBackground" StartPoint="0,0" EndPoint="0,1" > <GradientStop Color= "AliceBlue" Offset="0" /> <GradientStop Color= "Blue" Offset=".75" /> </LinearGradientBrush> 
  • And change your Style Setter for the background color:

     <Setter Property="Background" Value="{DynamicResource windowGradientBackground}" /> 

Steps 3 and 4 should be repeated in each project.XAML file as described above, but hey, you get a single Windows through the solution! And the same process can be applied to any controls that you want to have the same appearance, buttons, whatever.

For those who come to this late, I hope this helps, because I am sure that the original posters received this all that was invented many years ago.

Floor

+17
Mar 27 '12 at 21:11
source share

The designer does not work because you specify a DynamicResource. Please change this to StaticResource and everything will be fine.

To apply to all windows, you must remove x: Key from the style. Setting TargetType implicitly sets x: The key to what's in TargetType. However, in my tests this does not work, so I look through it.

If I set TargetType to x: Type TextBlock, the constructor works fine, it looks like it's a window that shows a different behavior.

+8
Jan 10 '09 at 23:23
source share

I researched this for several days and did it through the constructor of my own window class:

 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 } } 

Hope this helps someone

+2
Feb 25 '15 at 9:58
source share

For those struggling with a solution to the problem: how can I automatically customize my own style for all of my derived Window types? Below is the solution I came up with

NOTE. I really did not want to deduce from type Window or to insert XAML in each window to force to update style, etc. for reasons specific to my project (the consumers of my product used our universal library of reusable styles and create their own layout / windows, etc.), so I was really motivated to understand what kind of solution I got that I’m ready to live with any side effects.

You need to iterate over all created instances of the window and just force them to use the new custom style that you defined for the Window type. This is great for windows that are already created, but when a window or child window is created, it will not know if to use the new / user type that was declared for its base type; type of vanilla window. Therefore, it would be best to use LostKeyBoardFocus in MainWindow when it loses Focus in ChildWindow (IOW when the child window was created) and then calls this FixupWindowDerivedTypes ().

If someone has a better solution to “detect” when some type of window-derived is created, and so FixupWindowDerivedTypes () is called, which would be great. There might be something useful in handling WM_WINDOWPOSCHANGING in this area.

So, this solution is not elegant for everyone, but does its job without me to touch on any code or XAML associated with my windows.

  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, DefaultStyleKeyRetriever.GetDefaultStyleKey(window)); } } } } //Great little post here from Jafa to retrieve a protected property like DefaultStyleKey without using reflection. http://themechanicalbride.blogspot.com/2008/11/protected-dependency-properties-are-not.html //Helper class to retrieve a protected property so we can set it internal class DefaultStyleKeyRetriever : Control { /// <summary> /// This method retrieves the default style key of a control. /// </summary> /// <param name="control">The control to retrieve the default style key /// from.</param> /// <returns>The default style key of the control.</returns> public static object GetDefaultStyleKey(Control control) { return control.GetValue(Control.DefaultStyleKeyProperty); } } 
+1
May 10 '13 at 17:06
source share

You can add this code to the App.xaml.cs file:

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

After that, the style applied to the Window type also applies to all types derived from Window

+1
Jan 31 '17 at 15:15
source share

Given Gishu's answer, I figured out another workaround. But it can be a little strange. If you use the MVVM pattern, you can remove the code for your window and x: The markup of the class in the XAML file. This way you get a window instance or your own window, but not some instance of the "MainWindow" class, which is derived from the "Window" class and is marked as partial. I am creating a VS-like window, so I had to inherit the window class and extend its functionality. In this case, it will be possible to make the new class of windows partial, which would make it possible to code without inheritance.

0
Feb 02 '14 at 9:32
source share
  • you save all styles in one xaml file (example design.xaml)

  • and then call this file (design.xaml) xaml on all pages like this.

Like:

 <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Design.xaml"/> </ResourceDictionary.MergedDictionaries> 
-one
Nov 18 '13 at 9:25
source share



All Articles