Style inherittance between different target types - wpf

I don't know if I am just not understanding right. I am trying to make 2 different button styles for my application: BlueOnWhiteButton and WhiteOnBlueButton.
Both these buttons should be identical, but the foreground and backgrounds are reversed. So far, oh so simple.
Here is the catch: I need my buttons to have rounded corners. This simple requirement doesn't seem to be so simple after all. Also there maybe a little border of a different color on both versions.
Using some things I found on google and stack, I came up with this style for the first one, and it looked promising:
<Style x:Key="WhiteOnBlueButton"
TargetType="Button">
<Setter Property="Background" Value="{StaticResource MainBlue}" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontWeight" Value="bold" />
<Style.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="5" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="BorderBrush" Value="{StaticResource LightBlue}" />
</Style>
</Style.Resources>
</Style>
So far so good, my button looks how I want it. But then, when I try to make a second style underneath, I get an error at runtime because of the Style.Resources redefine. I'll save you the code block, figure the same with a different name and reversed colors.
I am trying to keep the use of the style as simple as possible, I have tried versions with templates, but it made the style a lot more complicated, and I even lost the button text...
What I would like to have is something like this:
<Style x:Key="RoundedButtonCornersNoBorder" TargetType="Border">
<Setter Property="CornerRadius" Value="4"/>
<Setter Property="BorderThickness" Value="0" />
</Style>
<Style x:Key="RoundedButtonCorners" TargetType="Border">
<Setter Property="CornerRadius" Value="4"/>
<Setter Property="BorderBrush" Value="{StaticResource LightBlue}" />
<Setter Property="BorderThickness" Value="2" />
</Style>
<Style x:Key="WhiteOnBlueButton"
TargetType="Button">
<Setter Property="Background" Value="{StaticResource MainBlue}" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontWeight" Value="bold" />
<!-- Somehow tell the borders should be taken from the style RoundedButtonCornersNoBorder-->
</Style>
<Style x:Key="BlueOnWhiteButton"
TargetType="Button">
<Setter Property="Background" Value="White" />
<Setter Property="Foreground" Value="{StaticResource MainBlue}" />
<Setter Property="FontWeight" Value="bold" />
<!-- Somehow tell the borders should be taken from the style RoundedButtonCorners-->
</Style>
Is there any way to code that without writing 300 lines of incomprehensible code?
The final goal is to apply the style by simply doing:
<Button
Style="{DynamicResource WhiteOnBlueButton}"
Content="CLICK ME!" />

You could move the Border Style in the Resources of a common base Style and derive the final Button Styles from the common base Style by means of the BasedOn property.
Do not set the BorderBrush in the Border Style, but either in the base or final Button Styles. The Border in the Button Template will pick it up from the Button via a TemplateBinding.
<Style x:Key="RoundedButtonCorners" TargetType="Button">
<Style.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="5"/>
<Setter Property="BorderThickness" Value="2"/>
</Style>
</Style.Resources>
<Setter Property="BorderBrush" Value="{StaticResource LightBlue}"/>
<Setter Property="FontWeight" Value="Bold" />
</Style>
<Style x:Key="WhiteOnBlueButton" TargetType="Button"
BasedOn="{StaticResource RoundedButtonCorners}">
<Setter Property="Background" Value="{StaticResource MainBlue}"/>
<Setter Property="Foreground" Value="White"/>
</Style>
<Style x:Key="BlueOnWhiteButton" TargetType="Button"
BasedOn="{StaticResource RoundedButtonCorners}">
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="{StaticResource MainBlue}"/>
</Style>

Turns out we have a library that has a button exposing the border directly.
Final styles look like this:
<Style x:Key="WhiteOnBlueButton" TargetType="telerik:RadButton">
<Setter Property="Foreground" Value="White" />
<Setter Property="Background" Value="{StaticResource MainBlue}" />
<Setter Property="FontWeight" Value="bold" />
<Setter Property="CornerRadius" Value="5" />
<Setter Property="BorderBrush" Value="{StaticResource LightBlue}" />
<Setter Property="BorderThickness" Value="0" />
</Style>
<Style x:Key="BlueOnWhiteButton" TargetType="telerik:RadButton">
<Setter Property="Foreground" Value="{StaticResource MainBlue}" />
<Setter Property="Background" Value="White" />
<Setter Property="FontWeight" Value="bold" />
<Setter Property="CornerRadius" Value="5" />
<Setter Property="BorderBrush" Value="{StaticResource LightBlue}" />
<Setter Property="BorderThickness" Value="0" />
</Style>
And then building my button:
<telerik:RadButton
x:Name="xamlFullTextSearchButton"
Style="{StaticResource BlueOnWhiteButton}"
Grid.Column="2"
Grid.Row="0"
Content="CLICK ME"
CornerRadius="4"/>
With this, I don't even loose the clicking animation! It's perfect for what I need!

Related

Remove Inner Border for a Textbox on ValidationError

I want to show a red border around a Textbox when a validation error occurs. This works, but there is also a blue border showing inside the red one, which I don't want to be shown. Is there a way to remove this?
Style for the Textbox
<Style x:Key="StandardTextbox" TargetType="{x:Type TextBox}">
<Setter Property="Height" Value="20"/>
<Setter Property="Margin" Value="10,5,10,5" />
<Setter Property="FontSize" Value="12"/>
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="BorderBrush" Value="{StaticResource Blau}"/>
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
Usage in Window:
<TextBox Grid.Row="0" Grid.Column="1"
Text="{Binding Path=Location,
UpdateSourceTrigger=PropertyChanged,
ValidatesOnDataErrors=True,
NotifyOnValidationError=true}"
Style="{StaticResource StandardTextbox}" Grid.ColumnSpan="3"/>
Enlargement:
That's because you're setting BorderBrush to Blau inside your Style. You can remove it if there is any Validation error by using Triggers. Like,
<Style x:Key="StandardTextbox" TargetType="{x:Type TextBox}">
<Setter Property="Height" Value="20"/>
<Setter Property="Margin" Value="10,5,10,5" />
<Setter Property="FontSize" Value="12"/>
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="BorderBrush" Value="{StaticResource Blau}"/>
<Setter Property="VerticalContentAlignment" Value="Center" />
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="BorderBrush" Value="Transparent"/>
</Trigger>
</Style.Triggers>
</Style>

Style as resources for custom user control

I am trying to modify Extended WPF toolkit wizard control which is a Custom control it has a default style in generic.xaml file but now I want to modify it so based on Wizard type it changes its style completely
<Style TargetType="{x:Type local:Wizard}">
<Style.Triggers>
<Trigger Property="WizardType" Value="Normal">
<Setter Property="Style" Value="{StaticResource StandartWizardTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
this is how I have its generic.xaml modified but StandardWizardTemplate is not resolved during insistence
<Style x:Key="StandartWizardTemplate" TargetType="{x:Type local:Wizard}">
<Setter Property="Background" Value="#F0F0F0" />
<Setter Property="BorderBrush" Value="#A0A0A0" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Grid />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
//Content of default template before modification
</Setter>
</Style>
Same file contains another style definition which changes Page ControlTemplate Based on trigger so I though I will be able to do the same thing for Wizard
<Style TargetType="{x:Type local:WizardPage}">
<Style.Triggers>
<Trigger Property="PageType" Value="Blank">
<Setter Property="Background" Value="#FFF0F0F0" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template" Value="{StaticResource BlankWizardPageTemplate}" />
</Trigger>
<Trigger Property="PageType" Value="Exterior">
<Setter Property="Background" Value="#FFFFFF" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="ExteriorPanelBackground" Value="#E3EFFF" />
<Setter Property="Template" Value="{StaticResource ExteriorWizardPageTemplate}" />
</Trigger>
<Trigger Property="PageType" Value="Interior">
<Setter Property="Background" Value="#FFF0F0F0" />
<Setter Property="BorderBrush" Value="{x:Static SystemColors.ActiveBorderBrush}" />
<Setter Property="BorderThickness" Value="0,1,0,0" />
<Setter Property="HeaderBackground" Value="#FFFFFF" />
<Setter Property="Template" Value="{StaticResource InteriorWizardPageTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
Can anyone provide me with the right Styling implementation so that my Wizard Custom Control can be styled in the same way as Page does?
OK I found solution for this problem, All i had to do was to create new ResourceDictionary and declare Wizard ControlTemplate with key set. After that inside Generic.xaml I created Marge Resource Dictionary and included all separate Control template dictionaries inside
After All my generic.xaml looks in this way now.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Converters="clr-namespace:CuratioCMS.Client.UI.Core.Converters"
xmlns:local="clr-namespace:CuratioCMS.Client.UI.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="./NormalWizardStyle.xaml" />
<ResourceDictionary Source="./StepBased.xaml" />
<ResourceDictionary Source="./MixedModeWizard.xaml" />
</ResourceDictionary.MergedDictionaries>
<Converters:WizardPageButtonVisibilityConverter x:Key="WizardPageButtonVisibilityConverter" />
<Style TargetType="{x:Type local:Wizard}">
<Style.Triggers>
<Trigger Property="WizardType" Value="Normal">
<Setter Property="Template" Value="{StaticResource NormalModeWizardTemplate}" />
</Trigger>
<Trigger Property="WizardType" Value="StepWisivle">
<Setter Property="Template" Value="{StaticResource StepModeWizardTemplate}" />
</Trigger>
<Trigger Property="WizardType" Value="MixedMode">
<Setter Property="Template" Value="{StaticResource MixedModeWizardTemplate}" />
</Trigger>
</Style.Triggers>
<Setter Property="Background" Value="#F0F0F0" />
<Setter Property="BorderBrush" Value="#A0A0A0" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Grid />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

Background not working in a setter

I am trying to make a simple resource dictionary for styles but the Background property is throwing an "Invalid Token". Setting the background directly in the property works fine. Here is an example using a button style:
<Style x:Key="ExampleButton"
TargetType="{x:Type Button}">
<Setter Property="Background"
Value="DarkGrey" />
<Setter Property="Width"
Value="100" />
<Setter Property="Height"
Value="30" />
<Style.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Background"
Value="Grey" />
</Trigger>
</Style.Triggers>
</Style>
i think the value need to be Value="Gray" and not Value="Grey"
or try to set your own "Shade of Gray", Value="#B2AFAF"

WPF datagrid template

I want to make a WPF datagrid look similar to the HTML grid in the following picture:
http://img443.imageshack.us/img443/2563/saltoftheearth.jpg
Does anyone know an easy way to do this ?
Regards,
S.
I managed to make it look like this ( http://img697.imageshack.us/img697/9417/failedwpfdatagridstylin.jpg ) using the following code in a resource file. However, it still does not look like the HTML counterpart ( http://img443.imageshack.us/img443/2563/saltoftheearth.jpg )....It has to many borders .... Any ideas on how to make this WPF datagrid look nicer ?
Value="12" />
<Style x:Key="DataGridCellStyle" TargetType="{x:Type my:DataGridCell}" >
<Setter Property="FontFamily"
Value="Tahoma" />
<Setter Property="FontSize"
Value="12" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderBrush" Value="Transparent" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="DataGridStyle"
TargetType="{x:Type my:DataGrid}" >
<Setter Property="RowHeaderWidth"
Value="0" />
<Setter Property="HorizontalAlignment"
Value="Left" />
<Setter Property="SelectionUnit"
Value="Cell" />
<Setter Property="SelectionMode"
Value="Single" />
<Setter Property="AutoGenerateColumns"
Value="false" />
<Setter Property="CanUserAddRows"
Value="False" />
<Setter Property="CanUserDeleteRows"
Value="False" />
<Setter Property="CanUserResizeRows"
Value="False" />
<Setter Property="CanUserResizeColumns"
Value="False" />
<Setter Property="CanUserSortColumns"
Value="True" />
<Setter Property="CanUserReorderColumns"
Value="False" />
<Setter Property="IsReadOnly"
Value="True" />
</Style>
You can take a look here, at C# Corner, there are lots of useful tutorials there, and Im pretty sure you can find it, like this one.

Creating a drop shadow style in XAML

I’m struggling a little bit with some XAML syntax I hope someone can advise on. I want to create an “Effect” type style resource which contains a DropShadowEffect definition which can be reused rather than always manually setting the properties. Here’s what I have:
<Style TargetType="DropShadowEffect" x:Name="DropShadowEffectStyle">
<Setter Property="BlurRadius" Value="5" />
<Setter Property="Direction" Value="315" />
<Setter Property="ShadowDepth" Value="2" />
<Setter Property="Opacity" Value="0.5" />
</Style>
<Style TargetType="TextBlock" x:Name="PageTabLabelStyle">
<Setter Property="FontSize" Value="16" />
<Setter Property="FontFamily" Value="Arial" />
<Setter Property="Foreground" Value="#EFEFEF" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Margin" Value="0, 10, 0, 10" />
<Setter Property="Effect" Value="{StaticResource DropShadowEffectStyle}" />
</Style>
This fails dismally each time it runs so I’m obviously missing something. I think it’s around the “Effect” property of the text block style expecting an “Effect” type rather than a “DopShadowEffect” type. Any ideas?
You cannot "style" an effect, because Style is a property of Control and an effect is not a Control.
What you really want to do is put the effect itself into the resource dictionary and use a StaticResource reference to point to it. Something like:
<UserControl.Resources>
<DropShadowEffect x:Key="dropShadow" BlurRadius="25" Direction="315" />
<Style TargetType="TextBlock" x:Name="PageTabLabelStyle">
<Setter Property="FontSize" Value="16" />
<Setter Property="FontFamily" Value="Arial" />
<Setter Property="Foreground" Value="#EFEFEF" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Margin" Value="0, 10, 0, 10" />
<Setter Property="Effect" Value="{StaticResource dropShadow}" />
</Style>
</UserControl.Resources>

Resources