In WPF i have a style for the control like below,
<Style TargetType="local:CustomControl">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Gray" />
<Setter Property="BorderThickness" Value="0,0,0,1" />
<Setter Property="Padding" Value="3,0,3,0" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
Now i need to override customcontrol border for some other place like below,
<Style TargetType="local:CustomControl" BasedOn="{StaticResource {x:Type local:CustomControl}}">
<Setter Property="BorderThickness" Value="1" />
</Style>
My problem is when i am using above code it override the 1st written code. is my code is correct.
Note: the base style is only written with target type. i need to override that control border in some other place without affect base code.
is it possible ? please help me to resolve this problem.
thanks in advance.
If you declare a Style without an x:Key, it will override the default style for that control.
<Style TargetType="local:CustomControl">
So the code above will effect all CustomControl elements throughout the entire application (or within the scope).
If you do not want to override the base style, you can give your Style an x:Key, like so:
<Style TargetType="local:CustomControl" x:Key="MyAwesomeStyle">
When you create your control, you will then have to reference the Style. Here's an example:
<local:CustomControl Style="{DynamicResource MyAwesomeStyle}" ... />
Accidentally I saw some example which can be useful in solving the mentioned problem. In your example own custom control has been used, in my example - a button.
<Grid>
<Button Style="{StaticResource AddButtonStyle}" Tag="Add" Click="addClick" />
</Grid>
Code for AddButtonStyle:
<Style x:Key="AddButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="Content" Value="✅"/>
</Style>
AddButtonStyle based on AppBarButtonStyle. Below code for it.
<Style x:Key="AppBarButtonStyle" TargetType="Button">
<Setter Property="MinWidth" Value="40" />
<Setter Property="Width" Value="100" />
<Setter Property="Height" Value="88" />
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontFamily" Value="Segoe UI Symbol" />
<Setter Property="FontSize" Value="18" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">. . .
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
On this example base, you must declare a Style with an x:Key, and should not set any value to Content (in you example BorderThickness) property in the inherited style.
Related
I've a style for my WPF buttons, defined in the main window:
<Window.Resources>
<Style TargetType="Button">
<Setter Property="Width" Value="Auto" />
<Setter Property="Height" Value="Auto" />
<Setter Property="FontSize" Value="12" />
<Setter Property="Foreground" Value="#FFFFFF" />
<Setter Property="Background" Value="#3fa9f5" />
...
</Style>
</Window.Resources>
In an UserControl, I want to set the content and the background depending on a binding:
<Button.Style>
<Style TargetType="Button">
<Setter Property="Content" Value="Text123" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=myControl, Path=IsHidden}"
Value="true">
<Setter Property="Content" Value="TextABC" />
<Setter Property="Background" Value="#ff1d25" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
The problem: The button in the UserControl looses all other properties it gets from the main window style (color, width, margins, ...).
I tried to let the UserControl button's style know the parent style via
BasedOn="{StaticResource {x:Type Button}}"
but with no result.
Let say I want to style a grid background like that :
<Page.Resources>
<Style x:key="MainGridStyle" TargetType="Grid">
<Setter Property="Background" Value="Blue" />
</Style>
</Page.Resources>
How can I make all TextBlocks inside that MainGridStyle Foreground=White through that Style?
Thanks
This works in WPF at least:
<Style x:key="MainGridStyle" TargetType="Grid">
<Setter Property="Background" Value="Blue" />
<Setter Property="TextElement.Foreground" Value="White" />
</Style>
I have a default Label Style
<Style x:Key="LabelStyle" TargetType="{x:Type Label}">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontSize" Value="13.333" />
<Setter Property="Foreground" Value="{StaticResource ForegroundBrush}" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
</Style>
<Style BasedOn="{StaticResource LabelStyle}" TargetType="{x:Type Label}" />
I then try to use a different style for a single Label
<Style x:Key="HeaderLabelStyle" TargetType="{x:Type Label}">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Foreground" Value="{StaticResource HeaderForegroundBrush}" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
</Style>
<Label Content="Text here" Name="someName" Style="{StaticResource HeaderLabelStyle}"/>
But for some reason the label always gets the default style. Why? Can this be overridden?
Thanks
So I realised that the default (string) template for Label is an indented TextBlock (styles are inherited)
Since I also was defining a global style for TextBlock
<Style x:Key="TextBlockStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource ForegroundBrush}" />
<Setter Property="FontSize" Value="13.333" />
<Setter Property="FontFamily" Value="Segoe UI" />
<Style BasedOn="{StaticResource TextBlockStyle}" TargetType="{x:Type TextBlock}" />
No matter how many types of Label I had I was always bound to use the template for TextBlock
So the solution was to define a dummy TextBlock class
namespace Theme
{
public class HeaderTextBlock : TextBlock
{
}
}
Then assign it its own global style
xmlns:this="clr-namespace:Theme"
<Style x:Key="HeaderTextBlockStyle" TargetType="this:HeaderTextBlock">
<Setter Property="Foreground" Value="{StaticResource HeaderForegroundBrush}" />
<Setter Property="FontSize" Value="13.333" />
<Setter Property="FontFamily" Value="Segoe UI" />
</Style>
<Style BasedOn="{StaticResource HeaderTextBlockStyle}" TargetType="{x:Type this:HeaderTextBlock}" />
And use TextBlocks instead of Labels (haven't figured out how to implement a Label child yet since (Label : TextBlock) = false
xmlns:theme="clr-namespace:Theme;assembly=Theme"
<theme:HeaderTextBlock Text="Some text" Name="titleLabel" Style="{StaticResource HeaderTextBlockStyle}"/>
I am trying to use a setter in my application to change to font size of all Controls. My Style is looking like this:
<Style x:Key="baseStyle" TargetType="{x:Type Control}">
<Setter Property="FontSize" Value="12" />
<Setter Property="Background" Value="{x:Null}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Width, ConverterParameter=1000, Converter={StaticResource DoubleToBoolConverter}, ElementName=window, Mode=OneWay}" Value="True">
<Setter Property="FontSize" Value="24" />
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
All of my substyles are looking like this
<Style BasedOn="{StaticResource baseStyle}" TargetType="{x:Type Button}">
...
</Style>
My problem is that my styles isnot applied to all controls. Labels for example seam to ignore my FontSize Setter
Default Style:
Triggered Style:
Do you actually refer to Label elements or TextBlock elements? Because the latter type is not a Control and won't be affected by your Style. This should work though:
<Style BasedOn="{StaticResource baseStyle}" TargetType="{x:Type Label}" />
But please always remember to provide a reproducible sample of your issue when asking a question: https://stackoverflow.com/help/mcve
how do I go about binding the Foreground Colour of one Style setter to the Fill Colour on another Style Setter, it should be the same object type. This is the code I have got below!
Getting these errors:
System.Windows.Data Error: 4 : Cannot find source for binding with
reference 'ElementName=MenuItemPath'. BindingExpression:Path=Fill;
DataItem=null; target element is 'TextBlock' (Name=''); target
property is 'Foreground' (type 'Brush')
<Style x:Key="MenuItemName" TargetType="TextBlock">
<Setter Property="Foreground" Value="{Binding ElementName=MenuItemPath, Path=Fill}" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
<ControlTemplate x:Key="MenuItem" TargetType="RadioButton">
<ControlTemplate.Resources>
<Style TargetType="Path" x:Name="MenuItemPath">
<Setter Property="Fill" Value="#FF22252C" />
<Setter Property="Height" Value="25" />
<Setter Property="Width" Value="25" />
<Setter Property="Stretch" Value="Uniform" />
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type RadioButton}}, Path=IsChecked}" Value="True">
<Setter Property="Fill" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
</ControlTemplate.Resources>
Personally I would create a separate Resource for storing the brush color, and reference it from both locations.
<SolidColorBrush Color="#FF22252C" x:Key="MenuFillColor" />
<Style x:Key="MenuItemName" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource MenuFillColor}" />
...
</Style>
<ControlTemplate x:Key="MenuItem" TargetType="RadioButton">
<ControlTemplate.Resources>
<Style TargetType="Path" x:Name="MenuItemPath">
<Setter Property="Fill" Value="{StaticResource MenuFillColor}" />
...
</Style>
</ControlTemplate.Resources>
</ControlTemplate>
That said, I've never actually tried binding to another Style's Setter.Value property... it might be possible assuming everything was the same scope. You look like you may have different scopes since you are using <ControlTemplate.Resources> to limit the scope of your MenuItemPath style to just that ControlTemplate. But personally I would not attempt it, and would assume any requirement that needed something like this could also be done some better way :)
It is not possible to access outer property of another style in wpf and that's why you have got binding error. Rather you can declare a color in your resources and from where you can access it.
I was making it more complicated than need be, I just added a DataTrigger which fixed the issue:
<Style x:Key="MenuItemName" TargetType="TextBlock">
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=MenuItemRadio}" Value="True">
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>