Styles defined in Application.Resources not applying to controls - wpf

I am trying to apply global application styles to certain control types, however adding these styles to Application.Resources does is not applying the styles to the elements in my views.
Example:
<Application x:Class="GUI.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="AliceBlue"></Setter>
<Setter Property="Margin" Value="20,20,20,20"></Setter>
<Setter Property="FontStyle" Value="Italic"></Setter>
</Style>
</Application.Resources>
</Application>
In all the examples I have found for applying application wide styles this has been how they say to do it, however it is not working for me. What am I doing wrong?
Thanks,
Alex.

Worked this out myself woops, the problem is I was not using the StartUpUri property to open my initial application view, I changed my start up process so it does use this property and this has fixed my problem.
My App.xaml now looks like this:
<Application x:Class="GUI.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="/Views/Application/SplashView.xaml">
<Application.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="Aqua"></Setter>
</Style>
</Application.Resources>
</Application>
Thanks,
Alex.

Eventhough this is an old post and has been answered. I came across this problem. I removed StartupUri and added and empty style (I used the question as an example):
<Application x:Class="GUI.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<!-- Added blank style first -->
<Style TargetType="Rectangle" />
<Style TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="AliceBlue"></Setter>
<Setter Property="Margin" Value="20,20,20,20"></Setter>
<Setter Property="FontStyle" Value="Italic"></Setter>
</Style>
</Application.Resources>
</Application>

Related

WPF window's background color is not set by style automatically

I have created simple WPF application with one window. What I want is to apply background color automatically to all windows. However, the color isn't applied.
Here's link to sample project. The following is XAML in App:
<Application x:Class="SampleWPFApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SampleWPFApp"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style TargetType="Window">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#FF3B444B" />
</Setter.Value>
</Setter>
</Style>
<Style TargetType="local:MainWindow" BasedOn="{StaticResource Window}" />
</Application.Resources>
</Application>
The logic was taken from here.
EDIT:
Well, I wasn't a bit fare about when the background isn't set - it's not set in VS editor. When program runs, background is OK. The solutions of Ragavan and mm8 do work, albeit they are the same with the difference that BasedOn="{StaticResource Window}" lets us omit the style's key (being Window the key itself).
Alas, the editor doesn't show the background, although setting the style explicitly (in MainWindow's XAML) makes background appear.
Basedon Will not bind directly window . Replace this code BasedOn="{StaticResource {x:Type Window}}"
App.Xaml
<Application x:Class="SampleWPFApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SampleWPFApp"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style TargetType="Window">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#FF3B444B" />
</Setter.Value>
</Setter>
</Style>
<Style TargetType="local:MainWindow" BasedOn="{StaticResource {x:Type Window}}"/>
</Application.Resources>
</Application>
In WPF, you set the styling resource for a type and not for an instance of type. Hence, below line should be removed.
Style TargetType="local:MainWindow" BasedOn="{StaticResource Window}" />
In your case, Windows background is being applied but it is just not visible because it may have a panel within. For example, when you create a new window, it will have Grid by default. Add below line and you will get the background for entire window. Please append &LT character in the below lines.
&LTStyle TargetType="{x:Type Grid}" BasedOn="{x:Null}">
&LTSetter Property="Background" Value="Black" />
&LT/Style>
Just give your style an x:Key and base the MainWindow style on this one. This works wonders for me:
<Application x:Class="SampleWPFApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SampleWPFApp"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="myWindowStyle" TargetType="Window">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#FF3B444B" />
</Setter.Value>
</Setter>
</Style>
<Style TargetType="local:MainWindow" BasedOn="{StaticResource myWindowStyle}" />
</Application.Resources>
</Application>

Trying to change window background color from XAML file

I'm playing around with the ExpressionDark.xaml theme. I'm setting the theme in App.xaml:
<Application x:Class="WpfApplication4.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary Source="Themes/ExpressionDark.xaml"/>
</Application.Resources>
</Application>
I looked at how they were setting the colors and styles of other controls, but am unable to produce the same result with the window.
If you like, you can see the XAML here.
Here's the XAML I'm trying:
<Style TargetType="{x:Type Window}">
<Setter Property="Background" Value="{DynamicResource BlackTestBrush}" />
<Style.Triggers>
</Style.Triggers>
</Style>
<SolidColorBrush x:Key="BlackTestBrush" Color="#FF000000" />
Any ideas on what I'm doing wrong here?
Thanks

Setting an Elements.Resource Style using BasedOn within a Resource Dictionary

I have a Resource Dictionary that I am using to define the look-and-feel (style) for my application.
I have just created another Resource Dictionary that contains DataTemplates that I am using on several different screens (and even multiple times within the same screen) to display my business objects.
I would like to change some of the default styles within my DataTemplates so that the controls fit better; however I would like the controls to inherit the same style as the rest of the screen. So, naturally I want to use the BasedOn property for this task.
The problem that I am having is that I'm not sure what to set the BasedOn property to.
For example, in the resource dictionary that contains my styles (called "myStyle.xaml") I have:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:primatives="clr-namespace:System.Windows.Controls.Primitives;assembly=PresentationFramework"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type Label}">
<Setter Property="Foreground" Value="#F5F5F5" />
<Setter Property="FontSize" Value="12"></Setter>
<Setter Property="Width" Value="120"></Setter>
<Setter Property="FontFamily" Value="Arial"></Setter>
</Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="FontSize" Value="12"></Setter>
<Setter Property="Width" Value="120"></Setter>
<Setter Property="Height" Value="25"></Setter>
<Setter Property="Background" Value="Black"></Setter>
</Style>
<!-- .... and so on .... -->
</ResourceDictionary>
I am using this resource in the following window:
<Window x:Class="SiteSetupWindow4"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:primatives="clr-namespace:System.Windows.Controls.Primitives;assembly=PresentationFramework"
Title="A Screen">
<Window.Resources>
<ResourceDictionary x:Key="defaultStyleX">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary x:Name="DefaultStyles" Source="Resources/myStyle.xaml" />
<ResourceDictionary x:Name="Templates" Source="Resources/myTemplates.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
Now, I have another Resource Dictionary that contains DataTemplates that I am using within my window. It is called "myTemplates". The style is applied to the DataTemplate as expected; however, I would like to overwrite some aspects of the style within the DataTemplate (Like width for example).
This is what I have tired, however I cannot get the BasedOn property to work...
(myTemplate.xaml)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DataTemplate x:Key="PanelInfo">
<StackPanel>
<StackPanel.Resources>
<Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="Width" Value="120" />
</Style>
<Style TargetType="Label">
<Setter Property="Width" Value="180" />
</Style>
<Style TargetType="ComboBox">
<Setter Property="Width" Value="120" />
</Style>
<StackPanel.Resources>
<StackPanel Orientation="Horizontal">
<Label Content="Type:"></Label>
<ComboBox>
<ComboBoxItem Content="{Binding Path=Type}" IsSelected="True"></ComboBoxItem>
</ComboBox>
<!--...and so on -->
</StackPanel>
</StackPanel>
</ResourceDictionary>
This fails....I have also tried using DynamicResource, but this also fails.
I'm not sure how to get around this.
Any advise would be greatly appreciated!
Thanks,
-Frinny
I was having the same problem with an extended Button Style.
The ResourceKey= is what solved it for me.
This worked:
<Style x:Name="ButtonVisibility"
TargetType="{x:Type Button}"
BasedOn="{StaticResource ResourceKey={x:Type Button}}">
The way you have BasedOn for a type is correct. This will work in theory as long as, at run time, the style that you are basing it on is merged into the tree correctly. Make sure you have the "myStyles.xaml" merged in correctly. You can check this by removing your style you tried to modify and make sure it displays correctly from your style in "myStyles.xaml."
If it isn't there are a lot of places you can go wrong, but it always helps to try merging the styles in the file you are working on, then work up the tree to see where it's missing.
This utility will help you look at what is happing in the tree at run time.
http://blois.us/Snoop/

WPF style causing loop

Why does the following XAML cause a stack overflow exception with some themes?
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ExpressionLight.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Margin" Value="5"/>
</Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}"/>
</ResourceDictionary>
</Application.Resources>
I have tried several themes found on internet and about half of them causes the exception.
Is there another way to apply a named Style as default?
Edit:
The problem is that the Theme adds the default style to the resource dictionary (an entry with the name System.Windows.Control.Button). Since a dictionary can only contain a single entry for each key it is not possible add a new default within the same resource dictionary.
Don't know why it leads to a "stackoverflow" instead of a "duplicate key" exception. It is probably because of the special handling of merged dictionaries which can contain duplicate keys.
The solution is to apply the named Style as default in code:
void AppStartup(object sender, StartupEventArgs args) {
this.Resources[typeof(Button)] = this.Resources["BaseButtonStyle"];
....
}
Since the BaseButtonStyle is staticly bound to the theme it is of course not possible to change theme at runtime with this solution.
you are having circular dependency in this code:
<Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Margin" Value="5"/>
</Style>
this style says that it is for TargetType Button, thats fine.
it also says that it is BasedOn the Style defined for TargetType Button, which is this itself.
Better to assign a key to the previous Style and then use that key in BasedOn.
EDIT:
After going through your code again it seems that there is a circular reference between your style and the style defined in ExpressionLight.xaml. A workaround would be to place resources at different levels.
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ExpressionLight.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Grid.Resources>
<Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Margin" Value="5"/>
</Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}"/>
</Grid.Resources>
............
...........
...........
</Grid>

WPF datagrid styling

I want to style a WPF datagrid and it seems to be really easy . As far as I understand I have to have code such as the following:
<Style x:Key="DataGridColumnHeaderStyle" TargetType="{x:Type Custom:DataGridColumnHeader}" >
<Setter Property="Background" Value="#88800080" />
<Setter Property="Foreground" Value="White" />
</Style>
But my question is ..where do I place this code and how do I let the datagrid know to use the style above ?
Regards,
S
Put it in the resource of the xaml (local or global). The easiest is to put it in the local resource of the current xaml file:
<Page Name="SomeName"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<Style x:Key="DataGridColumnHeaderStyle" TargetType="{x:Type Custom:DataGridColumnHeader}" >
<Setter Property="Background" Value="#88800080" />
<Setter Property="Foreground" Value="White" />
</Style>
</Page.Resources>
<!-- The rest of the xaml -->
</Page>
The best place to put styles is in a resource dictionary, referenced in App.xaml.
Resource dictionary ("StyleResources.xaml" in this example):
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="TextBlockRightAlign" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Right" />
</Style>
<Style x:Key="TextBlockTitle" TargetType="TextBlock">
<Setter Property="FontSize" Value="20" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
</ResourceDictionary>
Referencing the style dictionary in App.xaml:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="StyleResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<ValueConverters:PriceConverter x:Key="PriceConverter"/>
</ResourceDictionary>
</Application.Resources>
Using the definition in a datagrid (column formatting here, but should work for headers as well):
<data:DataGridTextColumn Header="Charge" Width="100"
Binding="{Binding Charge, Mode=TwoWay, Converter={StaticResource PriceConverter}}"
ElementStyle="{StaticResource TextBlockRightAlign}" />
Note that the element inside the cell is a TextBlock, so you can use a style with a target type of TextBlock.
As for the "Type DataGridColumnHeader was not found": you need a second xml namespace entry since the DataGridColumnHeader is in the System.Windows.Controls.Primitives namespace. You need something like
xmlns:dg="clr-namespace:Microsoft.Windows.Controls.Primitives;assembly=WPFToolkit"
and then reference the new namespace in your style, e.g.
<Style x:Key="DataGridColumnHeaderStyle" TargetType="{x:Type dg:DataGridColumnHeader}" >
Styles usually go:
<UserControl.Resources>
<Style x:Key="DataGridColumnHeaderStyle" TargetType="{x:Type Custom:DataGridColumnHeader}" >
<Setter Property="Background" Value="#88800080" />
<Setter Property="Foreground" Value="White" />
</Style>
</UserControl.Resources>
Use the appropriate container if this isn't within a UserControl you may use "Window" or whatever container you're in.
Also you need to reference it in your datagrid with:
<Custom:DataGrid ColumnHeaderStyle="{StaticResource DataGridColumnHeaderStyle}"/>

Resources