WPF ToggleButton XAML styling - wpf

So I have two toggle buttons that I am trying to combine - sort of. So the first button toggles the images based on whether it IsChecked is true or false, but this button has a border around it that I can't get rid of.
The second toggle button doesn't have a border and doesn't blink when clicked, but it also doesn't change images based on it's state.
What I want is the best of both worlds. Change the image AND get rid of the border. I have tried exactly 23 things and none of them work.
Here is the code I am using:
<ToggleButton x:Name="changeButBorderedBlinky" Margin="0,12,194,0" Width="82" Height="82" Background="Transparent" Padding="-1" Focusable="false" VerticalAlignment="Top" HorizontalAlignment="Right">
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Content">
<Setter.Value>
<Border BorderThickness="0" >
<Image Source="images/buttonimages/back2.png" Stretch="Fill" />
</Border>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content">
<Setter.Value>
<Border BorderThickness="0" >
<Image Source="images/buttonimages/back.png" Stretch="fill" />
</Border>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
<ToggleButton x:Name="noChangeNoBorder" Margin="0,12,104,0" VerticalAlignment="Top" HorizontalAlignment="Right" Height="80" Width="80" >
<ToggleButton.Template>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border x:Name="border" >
<Image x:Name="img" Source="images/buttonimages/back2.png" />
</Border>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
Thanks for any help on this. It's driving me insane.

Your customization options are endless in either case. Have you ever tried Expression Blend? It comes along with Visual Studio 2013 Community (which is free to use) and it would let you customize either control any way you want.
Here, done using Expression Blend, no blink, no border, image swapping:
<ToggleButton x:Name="changeButBorderedBlinky" Margin="0,12,194,0" Width="82" Height="82" Background="Transparent" Padding="-1" Focusable="false" VerticalAlignment="Top" HorizontalAlignment="Right">
<ToggleButton.Template>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsDefaulted" Value="True"/>
<Trigger Property="IsMouseOver" Value="True"/>
<Trigger Property="IsPressed" Value="True"/>
<Trigger Property="ToggleButton.IsChecked" Value="True"/>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="#FF838383"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ToggleButton.Template>
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Content">
<Setter.Value>
<Border BorderThickness="0" >
<Image Source="images/buttonimages/back2.png" Stretch="Fill" />
</Border>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content">
<Setter.Value>
<Border BorderThickness="0" >
<Image Source="images/buttonimages/back.png" Stretch="fill" />
</Border>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>

Try to use slightly modified XAML pertinent to your first ToggleButton:
<ToggleButton x:Name="changeButBorderedBlinky"
Margin="0,12,194,0"
Width="82" Height="82"
Background="Transparent"
Padding="-1"
Focusable="false"
VerticalAlignment="Top" HorizontalAlignment="Right">
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Content">
<Setter.Value>
<Image Source="images/buttonimages/back2.png" Stretch="Fill" />
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="images/buttonimages/back.png" Stretch="fill" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
You can also try to customize other properties, for eg:
<Setter Property="Background" Value="#FF1F3B53"/>
<Setter Property="Foreground" Value="#FF000000"/>
<Setter Property="BorderBrush" Value="Transparent">
For more styling options refer to: http://msdn.microsoft.com/en-us/library/cc296245%28v=vs.95%29.aspx
Hope this will help. Regards,

Related

WPF styling tab items as arrow-like

I want to style my TabControl to have items similar to this:
I tried to the combination of Border (with right thickness of 0) and triangle shaped polygon with pushing the polygon out of bound a bit to overlap, but its not really working as the out of bounds part of polygon gets hidden. Here is my attempt and now I am stuck and don't really know what else to try:
<!-- Styles -->
<Style TargetType="{x:Type TabItem}">
<Setter Property="Padding" Value="15 0 15 0" />
<Setter Property="Background" Value="#f5f5f5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid ClipToBounds="False">
<Border x:Name="PART_Border"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderThickness="1 1 0 1"
BorderBrush="LightGray">
<ContentPresenter ContentSource="Header" VerticalAlignment="Center" />
</Border>
<Polygon Points="0,0 20,25, 0,50"
Stroke="#e8e8e8"
Fill="#ffffff"
HorizontalAlignment="Right"
Margin="0 0 -10 0"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="PART_Border" Property="Background" Value="#ffffff" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Content -->
<TabControl>
<TabItem Header="First" />
<TabItem Header="Second" />
<TabItem Header="Third" />
</TabControl>
This will do the job for you:
<Style TargetType="{x:Type TabItem}">
<Setter Property="Background" Value="#f5f5f5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Path x:Name="Back" Data="M0,0 L 80,0 L100,20 L80,40 L0,40 L 20,20 " Stretch="None" VerticalAlignment="Stretch"
Stroke="#e8e8e8" StrokeThickness="2"
Fill="{TemplateBinding Background}"
HorizontalAlignment="Stretch" Margin="-30,0,0,0"/>
<ContentPresenter ContentSource="Header" VerticalAlignment="Center" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Back" Property="Fill" Value="#ffffff" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Instead of the border and polygon I used a Path to draw the shape for you.
You can use - (minus) values in margins to overlap items.
Result:

WPF - "Padding" in TabItem or a distance between header and content

I have a TabControl with a bunch of TabItems.
Between the TabItem's header and the content of the TabItem, I would like to have a distance of 15px.
I tried the TabItem's Padding property and set it to (0,15,0,0). But that didn't work.
I have tried to to set the TabItem's Template property but couldn't figure out how to set the distance.
The only solution I have found is to set a margin on the first control in the TabItem.
But I don't like that solution due to I have to implement that in each TabItem.
I would like a solution in a style so I can reuse the style for each TabItem instead.
Code
(Just copy-paste into a Window)
<Border BorderBrush="Black" BorderThickness="1">
<TabControl BorderThickness="0">
<TabControl.Resources>
<Style TargetType="{x:Type TabItem}" x:Key="TabItemStyle">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<Label x:Name="TabItemHeaderLabel"
Foreground="Orange"
FontSize="18"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Content="{Binding}" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type TabItem}}}" Value="True">
<Setter TargetName="TabItemHeaderLabel" Property="Foreground" Value="Blue"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Border x:Name="Chrome"
BorderBrush="Blue"
Background="Transparent">
<ContentPresenter ContentSource="Header"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Selector.IsSelected" Value="True">
<Setter TargetName="Chrome" Property="BorderThickness" Value="0,0,0,3"/>
</Trigger>
<Trigger Property="Selector.IsSelected" Value="False">
<Setter TargetName="Chrome" Property="BorderThickness" Value="0,0,0,0"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
<!-- TabItem 1-->
<TabItem Style="{DynamicResource TabItemStyle}"
Header="Tab 1">
<!-- Notice the margin -->
<Grid Margin="0,15,0,0"
Background="Lime" />
</TabItem>
<-- TabItem 2-->
<TabItem Style="{DynamicResource TabItemStyle}"
Header="Tab 2">
<Grid Background="Red" />
</TabItem>
</TabControl>
</Border>
If you select the Tab 1 you will notice a distance of 15px between the blue line in the header and the green Grid.
If you select the Tab 2 you will not see a distance between the blue line and the red grid.
Is there a better way to include the distance of 15px into the style in someway?
Can't you simply add a bottom margin to the Border element in the ControlTemplate?:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Border x:Name="Chrome"
BorderBrush="Blue"
Background="Transparent"
Margin="0,0,0,15">
<ContentPresenter ContentSource="Header"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Selector.IsSelected" Value="True">
<Setter TargetName="Chrome" Property="BorderThickness" Value="0,0,0,3"/>
</Trigger>
<Trigger Property="Selector.IsSelected" Value="False">
<Setter TargetName="Chrome" Property="BorderThickness" Value="0,0,0,0"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>

Add Content to Button in Style

Hello Im trying to override the default mouseover event on WPF.
I have managed to work that out, but now having a problem displaying any Text content
Style Setter:
<Style x:Key="MyButton" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Content" Value="Submit" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="Border" BorderThickness="0" BorderBrush="White" Background="#FF7AB800" Height="24" Margin="0,0,0.2,0" />
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True" >
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Heres my button code:
<Button x:Name="submitBtn" HorizontalAlignment="Left" Margin="402,296,0,0" VerticalAlignment="Top" Width="75" Foreground="Black" FontFamily="Calibri Light" FontSize="16" Style="{StaticResource MyButton}" Content="Submit"/>
You're missing the ContentPresenter. Also, I would recommend removing setting the content value from the style directly. You'd want to do this from within the control itself.
<Style x:Key="MyButton" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="Border"
BorderThickness="0"
BorderBrush="White"
Background="#FF7AB800"
Height="24"
Margin="0,0,0.2,0">
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"
Content="{TemplateBinding Content}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True" >
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Button x:Name="submitBtn"
HorizontalAlignment="Left"
Margin="402,296,0,0"
VerticalAlignment="Top"
Width="75"
Foreground="Black"
FontFamily="Calibri Light"
FontSize="16"
tyle="{StaticResource MyButton}"
Content="Submit"/>
First of all, you need to add x: type
<Style x:Key="MyButton" TargetType="x:Type Button">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Border Name="Border" BorderThickness="0" BorderBrush="White" Background="#FF7AB800" Height="24" Margin="0,0,0.2,0" />
<ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate TargetType="x:Type Button">

Custom color of the button on over on WPF [duplicate]

I have a button and I want to change the background color of button. but when I set the background property to a color like blue:
<Button Width="75" Height="25" Margin="6" Background="Blue"/>
and when the button has focus, the color changes in white and my color.
How can I set this white color to another color?
I believe that your problem is caused by the default ControlTemplate for the Button control. The colour animations that you describe are defined in this ControlTemplate and so you need to provide your own ControlTemplate to remove this behaviour:
<Button Content="Click Me" Background="Blue">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" Margin="{TemplateBinding Padding}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsFocused" Value="True">
<Setter TargetName="Border" Property="Background" Value="White" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
First Solution is
<Style x:Key="BtnStyle" TargetType="Button">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="gd" Height="120" Width="120" Background="{TemplateBinding Background}">
<ContentPresenter></ContentPresenter>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsFocused" Value="True">
<Setter Property="Background" Value="White" TargetName="gd"></Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Visibility" Value="Collapsed" TargetName="gd"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Button Width="75" Style="{StaticResource BtnStyle }" Content="ok" Height="25" Background="Blue"/>
second solution
<Style x:Key="Button_focusvisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border SnapsToDevicePixels="True" Background="White">
<TextBlock Text="Ok" ></TextBlock>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Button Width="75" FocusVisualStyle="{StaticResource Button_focusvisual }" Content="ok" Height="25" Background="Blue"/>

Graphics path minilanguage line aliasing

I am trying to draw a tick in a checkbox and for reason the aliasing doesn't seem to work, the lines are really jagged and don't look good at all. I am missing somthing?
<Style x:Key="{x:Type CheckBox}" TargetType="CheckBox">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="RenderOptions.EdgeMode" Value="Aliased"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<BulletDecorator Height="20" MinHeight="20">
<BulletDecorator.Bullet>
<Grid
Width="20"
Height="20">
<Border x:Name="Border"
CornerRadius="0"
Background="Black"
BorderThickness="0"
BorderBrush="Black"
Width="20"
Height="20" >
<Path
x:Name="CheckMark"
Stroke="White"
StrokeThickness="8"
Data="M 3,8 L 5,17,17,2"/>
</Border>
</Grid>
</BulletDecorator.Bullet>
<ContentPresenter Margin="0,0,0,0"
VerticalAlignment="Top"
HorizontalAlignment="Left"
RecognizesAccessKey="True" RenderOptions.EdgeMode="Aliased"/>
</BulletDecorator>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="false">
<Setter TargetName="CheckMark" Property="Visibility" Value="Collapsed"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Managed to fix this by setting the render options to unspecified.

Resources