Introduction
This is the second article in the WPFSpark series. WPFSpark is an Open Source project in CodePlex containing a library of user controls which can be used by the developer community. I was planning to write this article a few weeks ago, but I was preoccupied with creating a few more exciting controls for the WPFSpark
library. I will be describing these controls in my forthcoming articles.
In this article, I describe in detail about the second control in this library which I have developed. It is called the ToggleSwitch
control and it derives from ToggleButton
and provides a rich user experience. It supports only two states: True
or False
.
The previous article in the WPFSpark
series can be accessed here:
- WPFSpark: 1 of n: SprocketControl
Background
ToggleButton
System.Windows.Controls.Primitives.ToggleButton
is a base class for controls that can switch states, such as CheckBox
. It supports three states: True
, False
, and Null
.
FluidMoveBehavior
Before delving into the details of the ToggleSwitch
, one more WPF feature (which plays an important role in the ToggleSwitch
control) needs mention - FluidMoveBehavior
. FluidMoveBehavior
is an Expression Blend feature which allows you to animate a change in the position of an element. The animation looks very realistic as it allows the use of EasingFunction
s. Here are a few links which describe the FluidMoveBehavior
in much more detail:
ToggleSwitch Control Demystified
Simple ToggleSwitch
The first version of the ToggleSwitch
control which I created was the Simple ToggleSwitch
control. In order to create it, I defined a custom template for the ToggleButton
, which had a Grid
consisting of two columns and a single row.
The first column (Column 0) contained a TextBlock
which would define the text for the Checked state. Similarly, the second column (Column 1) contained a TextBlock
which would define the text for the Unchecked state.
Additionally, the template also contained a Border
depicting the Thumb of the ToggleSwitch
. The location of the Thumb, in the grid, would be either the first or the second column depending upon whether the ToggleSwitch
is in the Checked
or Unchecked
state.
Adding the FluidMoveBehavior
to the Grid
will ensure that whenever the state of the ToggleSwitch
changes, the movement of the Thumb from one column to the other will be animated and not instantaneous. (You should add references of Microsoft.Expression.Interactions.dll and System.Windows.Interactivity.dll to your project to get the FluidMoveBehaviour
.)
Here is the control template for the Simple ToggleSwitch
:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="clr-namespace:System.Windows.Interactivity;
assembly=System.Windows.Interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions">
<Style x:Key="ToggleSwitchStyle"
TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<ControlTemplate.Resources>
<Storyboard x:Key="Timeline1">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Glow"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000"
Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Timeline2">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Glow"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000"
Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Grid MinWidth="120"
MinHeight="40"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Background="Black">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<i:Interaction.Behaviors>
<ei:FluidMoveBehavior AppliesTo="Children"
Duration="0:0:0.25">
<ei:FluidMoveBehavior.EaseX>
<SineEase EasingMode="EaseIn" />
</ei:FluidMoveBehavior.EaseX>
</ei:FluidMoveBehavior>
</i:Interaction.Behaviors>
<Border Grid.ColumnSpan="2"
BorderBrush="LightGray"
Background="Transparent"
CornerRadius="6"
BorderThickness="1"></Border>
<TextBlock x:Name="OffText"
Grid.Column="0"
HorizontalAlignment="Center"
Text="Debug"
FontFamily="/CvisBuilder;Component/Resources/Font/#Segoe WP"
FontWeight="Light"
VerticalAlignment="Center"
Foreground="LawnGreen"
FontSize="{TemplateBinding FontSize}"></TextBlock>
<TextBlock x:Name="OnText"
Grid.Column="1"
HorizontalAlignment="Center"
FontFamily="/CvisBuilder;Component/Resources/Font/#Segoe WP"
FontWeight="Light"
Text="Release"
VerticalAlignment="Center"
Foreground="LawnGreen"
FontSize="{TemplateBinding FontSize}"></TextBlock>
<Border Name="Thumb"
Grid.Column="0"
BorderBrush="White"
BorderThickness="1"
Margin="3"
CornerRadius="4"
Background="#222222">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.507*" />
<RowDefinition Height="0.493*" />
</Grid.RowDefinitions>
<Border Opacity="0"
HorizontalAlignment="Stretch"
x:Name="Glow"
Width="Auto"
Grid.RowSpan="2"
CornerRadius="2">
<Border.Background>
<RadialGradientBrush>
<RadialGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform ScaleX="1.702"
ScaleY="2.743" />
<SkewTransform AngleX="0"
AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="-0.368"
Y="-0.152" />
</TransformGroup>
</RadialGradientBrush.RelativeTransform>
<GradientStop Color="LawnGreen"
Offset="0" />
<GradientStop Color="#44006400"
Offset="0.75" />
</RadialGradientBrush>
</Border.Background>
</Border>
<Border HorizontalAlignment="Stretch"
Margin="0,0,0,0"
x:Name="shine"
Width="Auto"
CornerRadius="2,2,0,0">
<Border.Background>
<LinearGradientBrush EndPoint="0.494,0.889"
StartPoint="0.494,0.028">
<GradientStop Color="#99FFFFFF"
Offset="0" />
<GradientStop Color="#33FFFFFF"
Offset="1" />
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="true">
<Setter Property="Grid.Column"
TargetName="Thumb"
Value="1" />
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Opacity"
Value="0.4" />
<Setter TargetName="OffText"
Property="Foreground"
Value="LightGray"></Setter>
<Setter TargetName="OnText"
Property="Foreground"
Value="LightGray"></Setter>
</Trigger>
<Trigger Property="IsPressed"
Value="True">
<Setter Property="Opacity"
TargetName="shine"
Value="0.6" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Trigger.EnterActions>
<BeginStoryboard
Storyboard="{StaticResource Timeline1}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard x:Name="Timeline2_BeginStoryboard"
Storyboard="{StaticResource Timeline2}" />
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Sophisticated ToggleSwitch
Though I was happy with the accomplishment of the Simple ToggleSwitch
creation, I was far from being satisfied. I wanted to make the ToggleSwitch
appear more realistic by making the TextBlock
s (used for displaying the two states of the ToggleSwitch
) appear along with the Thumb. I also wanted to make the ToggleSwitch
control easily skinnable by modifying a few properties.
To accomplish this, the first requirement was a WPF Grid
with rounded corners. Since the Grid
does not have the CornerRadius
property, the other option I had was to encapsulate the Grid
within a Border
and set the ClipToBounds
property of the Border
to true
. Then I found out that Border
(and all decorators) do not perform the clipping even though ClipToBounds
is set to true
.
For this purpose, I wrote the ClipBorder
class. It also allows the user to specify different corner radius for each of the corners of the border. (For more details, check out my article in my blog - ClipBorder: A WPF Border that clips.)
Now the ClipBorder
will encapsulate the Grid
(named PART_RootGrid
) that will be used to position the content of the ToggleSwitch
based on its state. This Grid
has three columns (Left
, Center
, and Right
). The width of each column is dynamically calculated based on the width of the Thumb.
The Content of the ToggleSwitch
is placed in another Grid
(named PART_ContentGrid
). This Grid
contains five columns (Left
, CenterLeft
, Center
, CenterRight
, and Right
).
The ContentGrid
contains the following:
CheckedBorder
- This defines the background that is displayed in the Checked
state of the ToggleSwitch
control. It occupies the Left
and CentreLeft
columns.
CheckedTextBlock
- This contains the text that is displayed in the Checked
state. It occupies the Left
column.
Thumb
- This contains the thumb of the ToggleSwitch
control. It occupies the CenterLeft
, Center
, and CenterRight
columns.
UncheckedBorder
- This defines the background that is displayed in the Unchecked
state of the ToggleSwitch
control. It occupies the CentreRight
and Right
columns.
UncheckedTextBlock
- This contains the text that is displayed in the Unchecked
state. It occupies the Right
column.
The Thumb
contains another Grid
which contains a Border
which provides a shine to the Thumb
.
The image below shows the outermost ClipBorder
and the ContentGrid
in details.
Here is the Exploded 3D view of a ToggleSwitch
control obtained using a wonderful tool called Snoop.
The ContentGrid
has a larger width than the RootGrid
, but since both are encapsulated within a ClipBorder
, the portion outside the ClipBorder
is clipped. Based on the state of the ToggleSwitch
(True
or False
) and the size of the thumb, the column within the RootGrid
where the ContentGrid
has to be placed is calculated.
The ThumbWidth
dependency property of the ToggleSwitch
control defines the width of the Thumb as a percentage of the Total Width of the ToggleSwitch
control. It can have values ranging from 10
to 90
(inclusive). Based on the ThumbWidth
, the width of each of the columns of the RootGrid
and the ContentGrid
and the margin of the ContentGrid
are calculated. The code below shows the calculation:
private void CalculateLayout()
{
if ((rootGrid == null) || (contentGrid == null))
return;
double thumbPercentage = ThumbWidth / 100.0;
double contentPercentage = 1 - thumbPercentage;
if (thumbPercentage <= 0.5)
{
rootGrid.ColumnDefinitions[0].Width =
new GridLength(thumbPercentage, GridUnitType.Star);
rootGrid.ColumnDefinitions[1].Width =
new GridLength(1.0 - (2 * thumbPercentage), GridUnitType.Star);
rootGrid.ColumnDefinitions[2].Width =
new GridLength(thumbPercentage, GridUnitType.Star);
TargetColumnInternal = 2;
Grid.SetColumnSpan(contentBorder, 1);
}
else
{
rootGrid.ColumnDefinitions[0].Width =
new GridLength(contentPercentage, GridUnitType.Star);
rootGrid.ColumnDefinitions[1].Width =
new GridLength(1.0 - (2 * contentPercentage), GridUnitType.Star);
rootGrid.ColumnDefinitions[2].Width =
new GridLength(contentPercentage, GridUnitType.Star);
TargetColumnInternal = 1;
Grid.SetColumnSpan(contentBorder, 2);
}
double leftRight = (1 - thumbPercentage) / (2 - thumbPercentage);
double centerLeftRight = 0.485 - leftRight;
double center = 0.03;
contentGrid.ColumnDefinitions[0].Width =
new GridLength(leftRight, GridUnitType.Star);
contentGrid.ColumnDefinitions[1].Width =
new GridLength(centerLeftRight, GridUnitType.Star);
contentGrid.ColumnDefinitions[2].Width =
new GridLength(center, GridUnitType.Star);
contentGrid.ColumnDefinitions[3].Width =
new GridLength(centerLeftRight, GridUnitType.Star);
contentGrid.ColumnDefinitions[4].Width =
new GridLength(leftRight, GridUnitType.Star);
contentBorderMargin = contentPercentage;
CalculateContentBorderMargin();
InvalidateVisual();
}
private void CalculateContentBorderMargin()
{
if (contentBorder != null)
{
contentBorder.Margin = new Thickness(-(this.Width * contentBorderMargin),
0, -(this.Width * contentBorderMargin), 0);
}
}
Here is the Control Template for the Sophisticated ToggleSwitch
control:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="clr-namespace:System.Windows.Interactivity;
assembly=System.Windows.Interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:wpfspark="clr-namespace:WPFSpark">
-->
<ControlTemplate x:Key="{ComponentResourceKey TypeInTargetAssembly=
wpfspark:ToggleSwitch, ResourceId=ToggleSwitchTemplate}"
TargetType="{x:Type wpfspark:ToggleSwitch}">
<ControlTemplate.Resources>
<Storyboard x:Key="BeginGlow">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Glow"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000"
Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="EndGlow">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Glow"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000"
Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
-->
<wpfspark:ClipBorder Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
CornerRadius="{Binding Path=CornerRadius,
RelativeSource={RelativeSource
AncestorType={x:Type wpfspark:ToggleSwitch}}}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid Name="PART_RootGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.4*"></ColumnDefinition>
<ColumnDefinition Width="0.2*"></ColumnDefinition>
<ColumnDefinition Width="0.4*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<i:Interaction.Behaviors>
<ei:FluidMoveBehavior AppliesTo="Children"
Duration="0:0:0.2">
<ei:FluidMoveBehavior.EaseX>
<QuarticEase EasingMode="EaseIn" />
</ei:FluidMoveBehavior.EaseX>
</ei:FluidMoveBehavior>
</i:Interaction.Behaviors>
-->
<Border Name="PART_ContentBorder"
Grid.Column="0"
CornerRadius="0"
Background="Transparent"
BorderThickness="0">
<Grid Name="PART_ContentGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.375*"></ColumnDefinition>
<ColumnDefinition Width="0.1*"></ColumnDefinition>
<ColumnDefinition Width="0.05*"></ColumnDefinition>
<ColumnDefinition Width="0.1*"></ColumnDefinition>
<ColumnDefinition Width="0.375*"></ColumnDefinition>
</Grid.ColumnDefinitions>
-->
-->
<Border x:Name="CheckedBorder"
Grid.Column="0"
Grid.ColumnSpan="2"
BorderThickness="0"
Margin="0"
CornerRadius="0"
Background="{Binding Path=CheckedBackground,
RelativeSource={RelativeSource
AncestorType={x:Type wpfspark:ToggleSwitch}}}">
</Border>
-->
<TextBlock x:Name="CheckedTextBlock"
Grid.Column="0"
Text="{Binding Path=CheckedText,
RelativeSource={RelativeSource
AncestorType={x:Type wpfspark:ToggleSwitch}}}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="{TemplateBinding FontFamily}"
FontWeight="{TemplateBinding FontWeight}"
FontSize="{TemplateBinding FontSize}"
Foreground="{Binding Path=CheckedForeground,
RelativeSource={RelativeSource
AncestorType={x:Type wpfspark:ToggleSwitch}}}"
></TextBlock>
-->
-->
<Border x:Name="UncheckedBorder"
Grid.Column="3"
Grid.ColumnSpan="2"
BorderThickness="0"
Margin="0"
CornerRadius="0"
Background="{Binding Path=UncheckedBackground,
RelativeSource={RelativeSource
AncestorType={x:Type wpfspark:ToggleSwitch}}}">
</Border>
-->
<TextBlock x:Name="UncheckedTextBlock"
Grid.Column="4"
Text="{Binding Path=UncheckedText,
RelativeSource={RelativeSource
AncestorType={x:Type wpfspark:ToggleSwitch}}}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="{TemplateBinding FontFamily}"
FontWeight="{TemplateBinding FontWeight}"
FontSize="{TemplateBinding FontSize}"
Foreground="{Binding Path=UncheckedForeground,
RelativeSource={RelativeSource
AncestorType={x:Type wpfspark:ToggleSwitch}}}">
</TextBlock>
-->
<wpfspark:ClipBorder x:Name="PART_Thumb"
Grid.Column="1"
Grid.ColumnSpan="3"
Margin="0"
BorderBrush="{Binding Path=ThumbBorderBrush,
RelativeSource={RelativeSource
AncestorType={x:Type wpfspark:ToggleSwitch}}}"
BorderThickness="{Binding Path=ThumbBorderThickness,
RelativeSource={RelativeSource
AncestorType={x:Type wpfspark:ToggleSwitch}}}"
CornerRadius="{Binding Path=ThumbCornerRadius,
RelativeSource={RelativeSource
AncestorType={x:Type wpfspark:ToggleSwitch}}}"
Background="{Binding Path=ThumbBackground,
RelativeSource={RelativeSource
AncestorType={x:Type wpfspark:ToggleSwitch}}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.507*" />
<RowDefinition Height="0.493*" />
</Grid.RowDefinitions>
<Border x:Name="Glow"
Opacity="0"
HorizontalAlignment="Stretch"
Width="Auto"
Grid.RowSpan="2"
CornerRadius="{Binding Path=ThumbCornerRadius,
RelativeSource={RelativeSource
AncestorType=
{x:Type wpfspark:ToggleSwitch}}}">
<Border.Background>
<RadialGradientBrush>
<RadialGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform ScaleX="1.702"
ScaleY="2.743" />
<SkewTransform AngleX="0"
AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="-0.368"
Y="-0.152" />
</TransformGroup>
</RadialGradientBrush.RelativeTransform>
<GradientStop
Color="{Binding Path=ThumbGlowColor,
RelativeSource={RelativeSource
AncestorType=
{x:Type wpfspark:ToggleSwitch}}}"
Offset="0.1" />
<GradientStop Color="#44222222"
Offset="0.8" />
</RadialGradientBrush>
</Border.Background>
</Border>
<Border x:Name="Shine"
HorizontalAlignment="Stretch"
Margin="0,0,0,0"
Width="Auto"
CornerRadius="{Binding Path=ThumbShineCornerRadius,
RelativeSource={RelativeSource
AncestorType=
{x:Type wpfspark:ToggleSwitch}}}">
<Border.Background>
<LinearGradientBrush EndPoint="0.494,0.889"
StartPoint="0.494,0.028">
<GradientStop Color="#99FFFFFF"
Offset="0" />
<GradientStop Color="#33FFFFFF"
Offset="1" />
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</wpfspark:ClipBorder>
</Grid>
</Border>
</Grid>
</wpfspark:ClipBorder>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsChecked"
Value="false">
<Setter Property="Grid.Column"
TargetName="PART_ContentBorder"
Value="{Binding Path=TargetColumnInternal,
RelativeSource={RelativeSource
AncestorType={x:Type wpfspark:ToggleSwitch}}}" />
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Opacity"
Value="0.4" />
<Setter TargetName="UncheckedTextBlock"
Property="Foreground"
Value="LightGray"></Setter>
<Setter TargetName="CheckedTextBlock"
Property="Foreground"
Value="LightGray"></Setter>
</Trigger>
<Trigger Property="ToggleButton.IsPressed"
Value="True">
<Setter Property="Opacity"
TargetName="Shine"
Value="0.6" />
</Trigger>
<Trigger Property="ToggleButton.IsMouseOver"
Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource BeginGlow}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource EndGlow}" />
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style TargetType="{x:Type wpfspark:ToggleSwitch}">
<Setter Property="Template"
Value="{StaticResource {ComponentResourceKey
TypeInTargetAssembly=wpfspark:ToggleSwitch,
ResourceId=ToggleSwitchTemplate}}" />
</Style>
</ResourceDictionary>
Update: WPFSpark v1.0
With the release of WPFSpark v1.0
, the following changes have been incorporated into ToggleSwitch:
- Added the
IsCheckedLeft
dependency property which indicates whether the checked content appears in the left or right side of the ToggleSwitch
.
- Added the
CheckedToolTip
property which is displayed when the ToggleSwitch
is in the Checked
state. Set this property to String.Empty
( ""
) to prevent this tooltip from displaying.
- Added the
UncheckedToolTip
property which is displayed when the ToggleSwitch
is in the Unchecked
state. Set this property to String.Empty
( ""
) to prevent this tooltip from displaying.
Check out the latest source code available at CodePlex to get the latest ToggleSwitch
.
ToggleSwitch Properties
Dependency Property |
Type |
Description |
Default Value |
CheckedBackground |
Brush |
Gets or sets the Background of the CheckedBorder in the ToggleSwitch control. |
White |
CheckedForeground |
Brush |
Gets or sets the Foreground color of the CheckedText . |
Black |
CheckedText |
String |
Gets or sets the text that is displayed when the ToggleSwitch control is in the Checked state. |
String.Empty |
CheckedToolTip |
String |
Gets or sets the ToolTip that is displayed when the ToggleSwitch is in the Checked state. Set this property to String.Empty ( "" ) to prevent this tooltip from displaying. |
String.Empty |
CornerRadius |
CornerRadius |
Gets or sets the CornerRadius of the outermost ClipBorder . |
0 |
IsCheckedLeft |
Boolean |
Gets or sets whether the checked content appears in the left or right side of the ToggleSwitch . |
True |
TargetColumnInternal |
Int32 |
Gets or sets the column in the RootGrid where the ContentGrid must be placed when the ToggleSwitch is in the Unchecked state. This property is used internally and should not be set by the user. |
0 |
ThumbBackground |
Brush |
Gets or sets the Background brush of the Thumb . |
Black |
ThumbBorderBrush |
Brush |
Gets or sets the color of the Thumb Border. |
Gray |
ThumbBorderThickness |
Thickness |
Gets or sets the thickness of the Thumb Border. |
0 |
ThumbCornerRadius |
CornerRadius |
Gets or sets the CornerRadius of the Thumb Border. |
0 |
ThumbGlowColor |
Color |
Gets or sets the Color of the glow over the Thumb when the mouse hovers over it. |
LawnGreen |
ThumbShineCornerRadius |
CornerRadius |
Gets or sets the CornerRadius of the Thumb Border's shine. |
0 |
ThumbWidth |
Double |
Gets or sets the width of the Thumb as a percentage of the Total width of the ToggleSwitch control. Value Range: 10 - 90 (inclusive). |
40 |
UncheckedBackground |
Brush |
Gets or sets the Background of the UncheckedBorder in the ToggleSwitch control. |
White |
UncheckedForeground |
Brush |
Gets or sets the Foreground color of the CheckedText . |
Black |
UncheckedText |
String |
Gets or sets the text that is displayed when the ToggleSwitch control is in the Unchecked state. |
String.Empty |
UncheckedToolTip |
String |
Gets or sets the ToolTip that is displayed when the ToggleSwitch is in the Unchecked state. Set this property to String.Empty ( "" ) to prevent this tooltip from displaying. |
String.Empty |
Skinning the ToggleSwitch
You can skin the ToggleSwitch
by modifying the above dependency properties. You can modify the background of the Checked and Unchecked states of the control. You can even modify the CornerRadius
of the Thumb
to get a variety of Thumb
shapes ranging from rectangle to rounded rectangles and even to circles too!
Here are a few examples of the various skins of the ToggleSwitch
control.
EndPoint
If you want to learn more about custom control development in WPF, I would suggest you read the book WPF Control Development Unleashed by Pavan Podila. It is deeply informative and contains lots of tips and tricks and other interesting facts regarding custom controls.
History
- December 21, 2011:
WPFSpark v1.0
released
- July 31, 2011:
WPFSpark v0.6
released