I was looking at this question and noticed that placing an implicit TextBlock
style in Application.Resources
applies that style to all TextBlocks, even those inside other controls such as Buttons
, ComboBoxes
, etc
<Application.Resources> <Style TargetType="{x:Type TextBlock}"> <Setter Property="Foreground" Value="Blue" /> </Style> </Application.Resources>
Placing the implicit style in Window.Resources
does not cross control template boundaries, so things like Buttons
and ComboBoxes
maintain their default black text.
<Window.Resources> <Style TargetType="{x:Type TextBlock}"> <Setter Property="Foreground" Value="Blue" /> </Style> </Window.Resources>
Furthermore, adding the default style in the Application.Resources
makes it so you can't overwrite that style with another implicit style.
<!-- Doesn't work if implicit style with same property is in Application.Resources --> <ComboBox.Resources> <Style TargetType="{x:Type TextBlock}"> <Setter Property="Foreground" Value="Red" /> </Style> </ComboBox.Resources>
My questions are:
Why is this?
Are there other differences between Application.Resources
and Windows.Resources
?
When should use one over the other?
I understand that Application.Resources
apply to the entire application, while Window.Resources
apply to the window only, however I want to know why the styles in Application
are treated differently than styles in Window
Windows Presentation Foundation (WPF) resources provide a simple way to reuse commonly defined objects and values. Resources in WPF allow you to set the properties of multiple controls at a time. For example you can set the background property on several elements in a WPF application using a single resource.
WPF supports different types of resources. These resources are primarily two types of resources: XAML resources and resource data files. Examples of XAML resources include brushes and styles. Resource data files are non-executable data files that an application needs.
You can use a style on any element that derives from FrameworkElement or FrameworkContentElement such as a Window or a Button. The most common way to declare a style is as a resource in the Resources section in a XAML file.
Template property, you can use a style to define or set a template. Designers generally allow you to create a copy of an existing template and modify it. For example, in the Visual Studio WPF designer, select a CheckBox control, and then right-click and select Edit template > Create a copy.
This is really the only special handling added to WPF and it was done by design. The code that implements it can be found in FrameworkElement
, in the method FindImplicitStyleResource
, which effectively does:
internal static object FindImplicitStyleResource(FrameworkElement fe, object resourceKey, out object source) { // ... DependencyObject boundaryElement = null; if (!(fe is Control)) boundaryElement = fe.TemplatedParent; // ... }
So the rule of thumb is that implicit Styles are always applied to controls (i.e. derives from Control
). Assuming the implicit Style can be found.
For elements used in a ControlTemplate
that do not derive from Control
, such as TextBlock
, the implicit Style look up will not cross it's templated parent. In your case above, this would be the ComboBox
.
I believe this was done so that non-application implicit Styles for TextBlock were not inadvertently applied to TextBlock
elements used in control templates, which the developer may or may not have known were there. The implicit Styles would only be applied to TextBlocks actually created by the developer in their own XAML.
The application implicit Styles would still allow global styling, such as increasing font size. But has probably caused more confusion than it's worth.
There is no good answer to say when to use one versus the other, as they each have their function. Obviously if you don't want to affect every TextBlock
in your application, you shouldn't put the style in the application resources.
But keep in mind that this affects any non-Control
element, such as Shape
elements.
Pretty plain as simple
If you want Resources to be shared among the ENTIRE application you would use Application.Resources
If you want Resources to be shared among the ENTIRE Window you would use Window.Resources
If you want Resources to be shared among a single control you would use (Whatever Control).Resources
Lets say you have multiple windows but you only want a default style in one but not the other then you would use Windoe.Resources
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With