I've got a wpf application that has 20+ windows, most of which serve as dialogs, and I'd like them all to have the same background color.
I've got a typed style for Window defined in a resource dictionary as follows
<Style TargetType="{x:Type Window}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid Background="{StaticResource WindowBackgroundBrush}">
<AdornerDecorator>
<ContentPresenter/>
</AdornerDecorator>
<ResizeGrip x:Name="WindowResizeGrip" HorizontalAlignment="Right" VerticalAlignment="Bottom" Visibility="Collapsed" IsTabStop="false"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ResizeMode" Value="CanResizeWithGrip">
<Setter TargetName="WindowResizeGrip" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I've got the dictionary include in the resources for the Application and each Window as follows
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Resources/Resources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Resources/Resources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
In Visual Studio, the background brush in the property editor says "Inheritance", but the value says "White". I see the desired background color in Visual Studio, but when I run the application I still see a white background. Can anyone explain what I'm doing wrong here? The WindowBackgroundBrush is getting applied to other controls correctly.
Note if I simplify the Style to be just
<Style TargetType="{x:Type Window}">
<Setter Property="Background" Value="Aqua"/>
</Style>
Visual Studio shows the Background brush as "Style Setter" as the value source and shows the Aqua as the value source, but the window is still white when the app launches.
You did it all correct. Its working at my place ... How are you applying style to window ? I applied as follows..
<Window x:Class="WpfApplicationScratchpad.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplicationScratchpad"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" Style="{StaticResource Style1}">
here Style1 is your style in resource dictionary. with the name 'Style1'
<Style x:Key="Style1" TargetType="{x:Type Window}">
<Setter Property="WindowStyle" Value="None"/>
<Setter Property="AllowsTransparency" Value="True"/>
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid Background="Beige">
<AdornerDecorator>
<ContentPresenter/>
</AdornerDecorator>
<ResizeGrip x:Name="WindowResizeGrip" HorizontalAlignment="Right" VerticalAlignment="Bottom" Visibility="Collapsed" IsTabStop="false"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ResizeMode" Value="CanResizeWithGrip">
<Setter TargetName="WindowResizeGrip" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Related
Can anyone help me with a simple template to make a WPF ToggleButton show "yes" or "no" depending on it's toggle state?
I dont want it to look like a button though, just a piece of text that either shows as yes or no.
I'd like it as a template that I can just add as a style to all my existing Toggle controls.
I tried with Blend but I am new to templating and didn't know how to do it.
Building up on #Batuu's reply, to be just left with the content as text just update the style to
Updated
<Style x:Key="OnOffToggleStyle" TargetType="ToggleButton">
<Setter Property="Content" Value="Off"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content" Value="On">
</Setter>
</Trigger>
</Style.Triggers>
</Style>
Addition here compared to original reply is
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
You basically set the template of the button to just be the content that it holds.
You can do this easily with a style:
<Window x:Class="WpfTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="OnOffToggleStyle" TargetType="ToggleButton">
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content">
<Setter.Value>
<TextBlock Text="Yes"/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Content">
<Setter.Value>
<TextBlock Text="No"/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<ToggleButton Style="{StaticResource OnOffToggleStyle}"/>
</Grid>
</Window>
vS 2008 with WPF toolkit installed and referenced.
In the Window1.xaml I added this line:
xmlns:my="http://schemas.microsoft.com/wpf/2008/toolkit"
It runs, grid displays with data, until I attempt to style the grid. I get an error when attempting to apply a style that centers the text. The error refers to App.xaml and is:
The type reference cannot find a public type named 'DataGridCell'. Line 9 Position 75.
My App.xaml
<Application x:Class="DataGridStyles.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
<Style x:Key="CenterCellStyle" TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
</Application.Resources>
</Application>
If the datagrid is part of the WPF toolkit, you'll need to add that namespace in your App.xaml too (xmlns:my="http://schemas.microsoft.com/wpf/2008/toolkit").
Then, just change your TargetType="{x:Type DataGridCell}" to TargetType="{x:Type my:DataGridCell}"
I have the following Style (stripped for brevity) and have some questions based on it. To my understanding, if a ControlTemplate replaces the entire visual tree of a control for which the Style is based on, what effect do the property Setters have then?
In this example, don't the property Setters for FontSize, Margin, Height etc. correspond to the respective properties on the CheckBox itself? If you replace the Template property of a control, what will these Setters then correspond to if the CheckBox is no longer rendering it's default appearance?
<Style x:Key="KeyName" TargetType="CheckBox">
<Setter Property="FontSize" Value="11" />
<Setter Property="Margin" Value="0 0 1 0" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Height" Value="18" />
... common property setters etc.
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<Border>
<StackPanel>
<Ellipse Name="Ellipse" Width="7" Height="7" />
<ContentPresenter Content="{TemplateBinding Content}" />
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.Setters>
<Setter Property="Foreground" Value="WhiteSmoke" />
</Trigger.Setters>
</Trigger>
... custom triggers etc ...
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
They are a way to provide an initial default value for properties on the object that's being styled, they don't auto force anything on the Template for you. They can however be used in the control template.
Values that are set using the setters in a style can be overridden by local values in the xaml. for example.
This xaml file draws a single label that has had it's style altered to include a grid that takes on the background color, I've defaulted the color to red in the setter and it appears as red.
<Window x:Class="ContextMenu.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="{x:Type Label}">
<Setter Property="Background" Value="Red"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Label}">
<Grid Background="{TemplateBinding Background}">
<TextBlock Text="{TemplateBinding Content}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Label>Test</Label>
</Window>
if I was to change the label line to blue on the instance of the label, you can see this overrides the setter.
<Window x:Class="ContextMenu.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="{x:Type Label}">
<Setter Property="Background" Value="Red"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Label}">
<Grid Background="{TemplateBinding Background}">
<TextBlock Text="{TemplateBinding Content}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Label Background="Blue">Test</Label>
</Window>
In my SL4 application, I have a Class called Images which has two properties (ImagePath, ImageName) and a method getImages() which retruns ObservableCollection list of all Images.
I need to create a Resource on my Page so that when a DataTemplate is loaded dynamically it can have access to the Images in one of its ComboBox field.
How can I do that?
<Page.Resources>
<local:Images x:Key="MyImages"/>
</Page.Resources>
But in my code behind file I cannot access the MyImages
You have 3 options
1. Use global app resource file.
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Assets/StylesA.xaml"/>
<ResourceDictionary Source="Assets/StylesB.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
And within StylesA.xaml just put style you have to use
<StackPanel>
<StackPanel.Resources>
<Style x:Key="HeaderStyle" TargetType="TextBlock">
<Setter Property="FontWeight" Value="Bold"></Setter>
<Setter Property="FontSize" Value="12"></Setter>
</Style>
</StackPanel.Resources>
<TextBlock Style="{StaticResource HeaderStyle}"></TextBlock> ....
2. Use local control Resources section.
<StackPanel>
<StackPanel.Resources>
<Style x:Key="HeaderStyle" TargetType="TextBlock">
<Setter Property="FontWeight" Value="Bold"></Setter>
<Setter Property="FontSize" Value="12"></Setter>
</Style>
</StackPanel.Resources>
<TextBlock Style="{StaticResource HeaderStyle}"></TextBlock> ....
3. Just use Page.Resources within your page
<navigation:Page.Resources>
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<Rectangle Margin="2" StrokeThickness="1" Stroke="#60000000" StrokeDashArray="1 2" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</navigation:Page.Resources>
I hope it will help. :)
I want to set the background property of all the usercontrols of my project.
I tried with
<style TargetType={x:Type UserControl}>
<setter property="Background" Value="Red" />
</style>
It compiles but didn't work.
¿Any Idea?
Thanks!
You can only set a a style to a specific class, so this will work (create a UserControl object, not very useful):
<Window.Resources>
<Style TargetType="{x:Type UserControl}">
<Setter Property="Background" Value="Red" />
</Style>
</Window.Resources>
<Grid>
<UserControl Name="control" Content="content"></UserControl>
</Grid>
But this doesn't (Create a class derived from UserControl):
<Window.Resources>
<Style TargetType="{x:Type UserControl}">
<Setter Property="Background" Value="Red" />
</Style>
</Window.Resources>
<Grid>
<l:MyUserControl Name="control" Content="content"></l:MyUserControl>
</Grid>
What you can do is either explicitly set the style using the Style property:
<Window.Resources>
<Style TargetType="{x:Type UserControl}" x:Key="UCStyle">
<Setter Property="Background" Value="Red" />
</Style>
</Window.Resources>
<Grid>
<l:MyUserControl Name="control" Content="content" Style="{StaticResource UCStyle}"></l:MyUserControl>
</Grid>
or create a style for each derived class, you can use BasedOn to avoid duplicating the style content:
<Window.Resources>
<Style TargetType="{x:Type UserControl}" x:Key="UCStyle">
<Setter Property="Background" Value="Red" />
</Style>
<Style TargetType="{x:Type l:MyUserControl}" BasedOn="{StaticResource UCStyle}" />
</Window.Resources>
<Grid>
<l:MyUserControl Name="control" Content="content"></l:MyUserControl>
</Grid>
I think you're missing some double quotes:
Try this:
<Window.Resources>
<Style TargetType="{x:Type UserControl}">
<Setter Property="Background" Value="Red" />
</Style>
</Window.Resources>
<Grid>
<UserControl Name="control" Content="content"></UserControl>
</Grid>