Slider On/Off Switch in WPF - wpf

I am looking for a WPF tutorial on creating a slide ON/OFF switch like on the iPhone.
Here is an example (the "Send all traffic" option) https://secure-tunnel.com/support/software_setup/iphone/images/iphone_vpn_settings.jpg

I haven't seen a tutorial on this exact problem, but i guess you can start by launching Expression Blend and putting a CheckBox on it. Then select the CheckBox, go to main menu - Object -> Edit Style -> Edit a Copy
This will make Blend generate the default style of CheckBox so you're able to modify it. Look at how things work there and you'll be able to achieve some results.
Basically (besides colors and brushes stuff) you'll need to look at triggers hooked up to the IsChecked property.
E.g. when IsChecked is True you move the rectangle to one of the sides, show the ON word and hide the OFF word. To animate this you only need to add trigger in- and out- animations.
UPD:
I've spent 10-15 minutes in blend to make a "prototype":
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="CheckBoxIPhone.Window1"
x:Name="Window"
Title="Window1"
Width="320"
Height="240"
FontFamily="Segoe UI"
FontSize="20"
WindowStartupLocation="CenterScreen"
>
<Window.Resources>
<Style x:Key="CheckBoxStyle1" TargetType="{x:Type CheckBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<ControlTemplate.Resources>
<Storyboard x:Key="OnChecking">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="slider" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="25"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="OnUnchecking">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="slider" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<ThicknessAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="slider" Storyboard.TargetProperty="(FrameworkElement.Margin)">
<SplineThicknessKeyFrame KeyTime="00:00:00.3000000" Value="1,1,1,1"/>
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<DockPanel x:Name="dockPanel">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" ContentTemplate="{TemplateBinding ContentTemplate}" RecognizesAccessKey="True" VerticalAlignment="Center"/>
<Grid Margin="5,5,0,5" Width="50" Background="#FFC0CCD9">
<TextBlock Text="ON" TextWrapping="Wrap" FontWeight="Bold" FontSize="12" HorizontalAlignment="Right" Margin="0,0,3,0"/>
<TextBlock HorizontalAlignment="Left" Margin="2,0,0,0" FontSize="12" FontWeight="Bold" Text="OFF" TextWrapping="Wrap"/>
<Border HorizontalAlignment="Left" x:Name="slider" Width="23" BorderThickness="1,1,1,1" CornerRadius="3,3,3,3" RenderTransformOrigin="0.5,0.5" Margin="1,1,1,1">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Border.RenderTransform>
<Border.BorderBrush>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFFFFFFF" Offset="0"/>
<GradientStop Color="#FF4490FF" Offset="1"/>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF8AB4FF" Offset="1"/>
<GradientStop Color="#FFD1E2FF" Offset="0"/>
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource OnUnchecking}" x:Name="OnUnchecking_BeginStoryboard"/>
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource OnChecking}" x:Name="OnChecking_BeginStoryboard"/>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<CheckBox HorizontalAlignment="Center" Style="{DynamicResource CheckBoxStyle1}" VerticalAlignment="Center" Content="CheckBox"/>
</Grid>
</Window>
I'm also suggesting you to read about Styles and Templates in WPF if you're interested.

I created some styles based on the post by arconaut in orange and blue.
Screenshot:
I wanted my style to closer match the On/Off Switch style of iOS devices. One difference in this style is, that the sliding animation does only slide the switch and not the indicators below. Maybe if i can find some time I will modify it that way. Until then I want to share my result. It's not perfect, but here is the code.
<LinearGradientBrush x:Key="CheckedBlue" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#FF285AB3" Offset="0" />
<GradientStop Color="#FF4184EC" Offset="0.5" />
<GradientStop Color="#FF558BED" Offset="0.5" />
<GradientStop Color="#FF7DACF0" Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="CheckedOrange" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#FFCA6A13" Offset="0" />
<GradientStop Color="#FFF67D0C" Offset="0.2" />
<GradientStop Color="#FFFE7F0C" Offset="0.2" />
<GradientStop Color="#FFFA8E12" Offset="0.5" />
<GradientStop Color="#FFFF981D" Offset="0.5" />
<GradientStop Color="#FFFCBC5A" Offset="1" />
</LinearGradientBrush>
<SolidColorBrush x:Key="CheckedOrangeBorder" Color="#FF8E4A1B" />
<SolidColorBrush x:Key="CheckedBlueBorder" Color="#FF143874" />
<Style x:Key="OrangeSwitchStyle" TargetType="{x:Type CheckBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<ControlTemplate.Resources>
<Storyboard x:Key="OnChecking">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="slider" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="53" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="OnUnchecking">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="slider" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<DockPanel x:Name="dockPanel">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" ContentTemplate="{TemplateBinding ContentTemplate}" RecognizesAccessKey="True" VerticalAlignment="Center" />
<Grid>
<Border x:Name="BackgroundBorder" BorderBrush="#FF939393" BorderThickness="1" CornerRadius="3" Height="27" Width="94">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#FFB5B5B5" Offset="0" />
<GradientStop Color="#FFDEDEDE" Offset="0.1" />
<GradientStop Color="#FFEEEEEE" Offset="0.5" />
<GradientStop Color="#FFFAFAFA" Offset="0.5" />
<GradientStop Color="#FFFEFEFE" Offset="1" />
</LinearGradientBrush>
</Border.Background>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition /><ColumnDefinition />
</Grid.ColumnDefinitions>
<Ellipse x:Name="Off" Width="14" Height="14" Stroke="#FF7A7A7A" StrokeThickness="2" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Line x:Name="On" X1="0" Y1="0" X2="0" Y2="14" Stroke="#FF7A7A7A" StrokeThickness="2" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Border>
<Border BorderBrush="#FF939393" HorizontalAlignment="Left" x:Name="slider" Width="41" Height="27" BorderThickness="1" CornerRadius="3" RenderTransformOrigin="0.5,0.5" Margin="0">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Border.RenderTransform>
<Border.Background>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFF0F0F0" Offset="0" />
<GradientStop Color="#FFCDCDCD" Offset="0.1" />
<GradientStop Color="#FFFBFBFB" Offset="1" />
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource OnUnchecking}" x:Name="OnUnchecking_BeginStoryboard" />
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource OnChecking}" x:Name="OnChecking_BeginStoryboard" />
</Trigger.EnterActions>
<Setter TargetName="On" Property="Stroke" Value="White" />
<Setter TargetName="Off" Property="Stroke" Value="White" />
<!-- Change Orange or Blue color here -->
<Setter TargetName="BackgroundBorder" Property="Background" Value="{StaticResource CheckedOrange}" />
<Setter TargetName="BackgroundBorder" Property="BorderBrush" Value="{StaticResource CheckedOrangeBorder}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<!-- ToDo: Add Style for Isenabled == False -->
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

A few open source ToggleSwitches:
ToggleSwitch looks good, available by NuGet, too.
MahApps ToggleSwitch is a part of bigger MahApps library of Metro like controls.

I just posted an entry in regards to this which provides a proper sliding action, full configurability and doesn't require to be a fixed size (got annoyed as I couldn't find anything on the web that provided a solution like that).
You can find it here: http://itsallaboutthexaml.blogspot.com/2012/01/variables-in-animation.html

Well I set out to accomplish this same task but the examples fell a little short of production code. For instance what happens if you put text into the control like On/Off or a localized version of the text, answer is you have to define the size of the control because you cannot modify an animation or template triggers after you have rendered the control. This gives you a one-size-fits-all solution that will not work with localized text.
My solution was to create the template for the control dynamically using the control's Loaded event and the FrameworkElementFactory class. I have to say it was by far complicated but could be achieved. Simply put, in your code behind, create a template as described, setup dependency properties for your on/off text, use the text metrics to determine the control's width, height and animation values.
I'm sorry that I cannot post the solution since it belongs to Avanquest now. :(
Look for it in SystemSuite and Fix-It 12.

I like the nice prototype from arconaut and I added some code to get the border rounded.
You have to remove the "Background" property from the Grid declaration and add this lines between the Grid declaration and the first TextBlock declaration:
<Border
x:Name="back"
CornerRadius="3,3,3,3"
BorderThickness="1"
BorderBrush="#FFC0CCD9"
>
<Rectangle Fill="#FFC0CCD9"/>
</Border>

Related

Set Fill to LinearGradientBrush on Button Click

For reference, I am using this MSDN tutorial: https://msdn.microsoft.com/en-us/library/bb613545(v=vs.100).aspx
I have finished the tutorial, and I simply wanted to change the Click EventTrigger animation from the 360 spin to a simple change of the LinearGradientBrush.
My GradientStopCollections as per the tutorial. One is an altered one that I want to use in the animation when I click the button
<GradientStopCollection x:Key="MyGlassGradientStopsResource">
<GradientStop Offset="0.2" Color="WhiteSmoke" />
<GradientStop Offset="0.4" Color="Transparent" />
<GradientStop Offset="0.5" Color="WhiteSmoke" />
<GradientStop Offset="0.75" Color="Transparent" />
<GradientStop Offset="0.9" Color="WhiteSmoke" />
<GradientStop Offset="1" Color="Transparent" />
</GradientStopCollection>
<GradientStopCollection x:Key="MyRedGlassGradientStopsResource">
<GradientStop Offset="0.2" Color="IndianRed" />
<GradientStop Offset="0.4" Color="Transparent" />
<GradientStop Offset="0.5" Color="IndianRed" />
<GradientStop Offset="0.75" Color="Transparent" />
<GradientStop Offset="0.9" Color="IndianRed" />
<GradientStop Offset="1" Color="Transparent" />
</GradientStopCollection>
<LinearGradientBrush x:Key="MyGlassBrushResource"
GradientStops="{StaticResource MyGlassGradientStopsResource}"
Opacity="0.75"
StartPoint="0,0"
EndPoint="1,1" />
<LinearGradientBrush x:Key="MyRedGlassBrushResource"
GradientStops="{StaticResource MyRedGlassGradientStopsResource}"
Opacity="0.75"
StartPoint="0,0"
EndPoint="1,1" />
The button itself. The rectangle being affected is the glassCube rectangle.
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="{StaticResource GrayBlueGradientBrush}" />
<Setter Property="Width" Value="90" />
<Setter Property="Margin" Value="10" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
ClipToBounds="True">
<!-- Outer rectangle with rounded corners -->
<Rectangle x:Name="outerRectangle"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Fill="Transparent"
RadiusX="20"
RadiusY="20"
Stroke="{TemplateBinding Background}"
StrokeThickness="5" />
<!-- Inner rectangle with rouded corners -->
<Rectangle x:Name="innerRectangle"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Fill="{TemplateBinding Background}"
RadiusX="20"
RadiusY="20"
Stroke="Transparent"
StrokeThickness="20" />
<!-- Glass Rectangle -->
<Rectangle x:Name="glassCube"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Fill="{StaticResource MyGlassBrushResource}"
Opacity="0"
RadiusX="10"
RadiusY="10"
RenderTransformOrigin="0.5,0.5"
StrokeThickness="2">
<Rectangle.Stroke>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.0" Color="LightBlue" />
<GradientStop Offset="1.0" Color="Gray" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.Stroke>
<!--
These tranforms have no effect as they are declared here.
The reason the transforms are included is to be targets for animation
(See later)
-->
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform />
<RotateTransform />
</TransformGroup>
</Rectangle.RenderTransform>
<!-- A BevelBitmapEffect if applied to give the button a "Bevelled" look -->
<Rectangle.BitmapEffect>
<BevelBitmapEffect />
</Rectangle.BitmapEffect>
</Rectangle>
<!-- Present content (text) of the button -->
<DockPanel Name="myContentPresenterDockPanel">
<ContentPresenter x:Name="myContentPresenter"
Margin="20"
Content="{TemplateBinding Content}"
TextBlock.Foreground="Black" />
</DockPanel>
</Grid>
</ControlTemplate>
<!---Snipped the triggers-->
</Setter.Value>
And this is the trigger I am trying to use to change the Fill of the glassCube rectangle from the MyGlassGradientStopsResource brush to the MyGlassGradientStopsResource brush.
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.5"
Storyboard.TargetName="glassCube"
Storyboard.TargetProperty="Rectangle.Fill"
To="{StaticResource MyRedGlassBrushResource}"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
However, trying to do this gives me an XAMLParseException. The error in the error list shows as An object of the type "System.Windows.Media.LinearGradientBrush" cannot be applied to a property that expects the type "System.Nullable`1[[System.Windows.Media.Color, PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]".
Any idea what I might be doing wrong? I've tried finding out how to change a Fill to a different LinearGradientBrush in an EventTrigger, but to no avail. I may just suck at wording my searches, or at searching in general. Any help is greatly appreciated
I did some modification of your style. Also, i fixed your Storyboard.
It should now work properly.
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="{StaticResource GrayBlueGradientBrush}" />
<Setter Property="Width" Value="90" />
<Setter Property="Margin" Value="10" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" ClipToBounds="True">
<Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="Transparent" RadiusX="20" RadiusY="20" Stroke="{TemplateBinding Background}" StrokeThickness="5" />
<Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="{TemplateBinding Background}" RadiusX="20" RadiusY="20" Stroke="Transparent" StrokeThickness="20" />
<Rectangle x:Name="glassCube" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Opacity="1" RadiusX="10" RadiusY="10" RenderTransformOrigin="0.5,0.5" StrokeThickness="2">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="Fill" Value="{StaticResource MyGlassBrushResource}"></Setter>
</Style>
</Rectangle.Style>
<Rectangle.Stroke>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.0" Color="LightBlue" />
<GradientStop Offset="1.0" Color="Gray" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.Stroke>
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform />
<RotateTransform />
</TransformGroup>
</Rectangle.RenderTransform>
<!-- A BevelBitmapEffect if applied to give the button a "Bevelled" look -->
<Rectangle.BitmapEffect>
<BevelBitmapEffect />
</Rectangle.BitmapEffect>
</Rectangle>
<!-- Present content (text) of the button -->
<DockPanel Name="myContentPresenterDockPanel" HorizontalAlignment="Center">
<ContentPresenter x:Name="myContentPresenter" Content="{TemplateBinding Content}" TextBlock.Foreground="Black" />
</DockPanel>
</Grid>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="glassCube" Storyboard.TargetProperty="Fill" Duration="0:0:0.5" BeginTime="0">
<ObjectAnimationUsingKeyFrames.KeyFrames>
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource MyRedGlassBrushResource}" />
</ObjectAnimationUsingKeyFrames.KeyFrames>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Note
You cannot set a Brush as ColorAnimation. Use a ObjectAnimationUsingKeyFrames instead. If you still need a BrushAnimation, have a look here

button animation on click then executing the code behind

I have a button which it opens a new window in XAML. I introduced succesfully a storyboard which animates the button make it turn on button click but the thing is when I applied to make it open a new window it stop it doesn't execute the story it just opens a new window and when I remove the code on button click to open a new window it animates just fine. What I need is to make it execute the animation first i.e the storyboard on button click and then open a new window.
Kindly help,
Best regards,
in Xaml.app
<Application x:Class="Shopping_Mall_Test_Project.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<GradientStopCollection x:Key="MyGlassGradientStopsResource">
<GradientStop Color="WhiteSmoke" Offset="0.2" />
<GradientStop Color="Transparent" Offset="0.4" />
<GradientStop Color="WhiteSmoke" Offset="0.5" />
<GradientStop Color="Transparent" Offset="0.75" />
<GradientStop Color="WhiteSmoke" Offset="0.9" />
<GradientStop Color="Transparent" Offset="1" />
</GradientStopCollection>
<LinearGradientBrush x:Key="MyGlassBrushResource"
<LinearGradientBrush x:Key="GrayBlueGradientBrush"
StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="DarkGray" Offset="0" />
<GradientStop Color="#CCCCFF" Offset="0.5" />
<GradientStop Color="DarkGray" Offset="1" />
</LinearGradientBrush>
StartPoint="0,0" EndPoint="1,1" Opacity="0.75"
GradientStops="{StaticResource MyGlassGradientStopsResource}" />
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="{StaticResource GrayBlueGradientBrush}" />
<Setter Property="Width" Value="80" />
<Setter Property="Margin" Value="10" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}" ClipToBounds="True">
<!-- Outer Rectangle with rounded corners. -->
<Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" Stroke="{TemplateBinding Background}"
RadiusX="20" RadiusY="20" StrokeThickness="5" Fill="Transparent" />
<!-- Inner Rectangle with rounded corners. -->
<Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" Stroke="Transparent"
StrokeThickness="20"
Fill="{TemplateBinding Background}" RadiusX="20" RadiusY="20"
/>
<!-- Glass Rectangle -->
<Rectangle x:Name="glassCube" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
StrokeThickness="2" RadiusX="10" RadiusY="10" Opacity="0"
Fill="{StaticResource MyGlassBrushResource}"
RenderTransformOrigin="0.5,0.5">
<Rectangle.Stroke>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.0" Color="LightBlue" />
<GradientStop Offset="1.0" Color="Gray" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.Stroke>
<!-- These transforms have no effect as they
are declared here.
The reason the transforms are included is to be targets
for animation (see later). -->
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform />
<RotateTransform />
</TransformGroup>
</Rectangle.RenderTransform>
<!-- A BevelBitmapEffect is applied to give the button a
"Beveled" look. -->
<Rectangle.BitmapEffect>
<BevelBitmapEffect />
</Rectangle.BitmapEffect>
</Rectangle>
<!-- Present Text of the button. -->
<DockPanel Name="myContentPresenterDockPanel">
<ContentPresenter x:Name="myContentPresenter" Margin="20"
Content="{TemplateBinding Content}" TextBlock.Foreground="Black" />
</DockPanel>
</Grid>
<ControlTemplate.Triggers>
<!-- Animation fires when button is clicked, causing glass to spin. -->
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="glassCube"
Storyboard.TargetProperty=
"(Rectangle.RenderTransform).(TransformGroup.Children)[1].(RotateTransform.Angle)"
By="360" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<!-- Animations that start when mouse enters and leaves button. -->
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard Name="mouseEnterBeginStoryboard">
<Storyboard>
<!-- This animation makes the glass rectangle shrink in the X direction. -->
<DoubleAnimation Storyboard.TargetName="glassCube"
Storyboard.TargetProperty=
"(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"
By="-0.1" Duration="0:0:0.5" />
<!-- This animation makes the glass rectangle shrink in the Y direction. -->
<DoubleAnimation
Storyboard.TargetName="glassCube"
Storyboard.TargetProperty=
"(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"
By="-0.1" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<EventTrigger.Actions>
<!-- Stopping the storyboard sets all animated properties back to default. -->
<StopStoryboard BeginStoryboardName="mouseEnterBeginStoryboard" />
</EventTrigger.Actions>
</EventTrigger>
<!-- Set properties when mouse pointer is over the button. -->
<Trigger Property="IsMouseOver" Value="True">
<!-- Below are three property settings that occur when the
condition is met (user mouses over button). -->
<!-- Change the color of the outer rectangle when user mouses over it. -->
<Setter Property ="Rectangle.Stroke" TargetName="outerRectangle"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<!-- Sets the glass opacity to 1, therefore, the glass "appears" when user mouses over it. -->
<Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" />
<!-- Makes the text slightly blurry as though you were looking at it through blurry glass. -->
<Setter Property="ContentPresenter.BitmapEffect" TargetName="myContentPresenter">
<Setter.Value>
<BlurBitmapEffect Radius="1" />
</Setter.Value>
</Setter>
</Trigger>
<!-- Set properties when button has focus. -->
<Trigger Property="IsFocused" Value="true">
<Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" />
<Setter Property="Rectangle.Stroke" TargetName="outerRectangle"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
in code:
public MainWindow()
{
InitializeComponent();
}
private void button3_Click(object sender, RoutedEventArgs e)
{
Storyboard st = (Storyboard)TryFindResource("glassCube");
st.Begin();
Close();
}
private void button2_Click(object sender, RoutedEventArgs e)
{
Storyboard st = (Storyboard)TryFindResource("glassCube");
st.Begin();
Registration_Form win1 = new Registration_Form();
win1.Show();
this.Close();
}
}
thank you in advance

Convert ListBox template into Button Template

I having hard time converting an ItemTemaplte of ListBox to a Button from the example {Surfin}Video
Viewer Demo ,
I want a button style like an Item in this ListBox . Each Item in the ListBox have
Name&Image with the style define there. I noob to Template & Styles , If some1 with more expreince can
make it easily, I appreciate . ( better to run the demo to see how the 'button'( listbox item) looks like , I need the look and feel of the button only :) ignore the 'video' )
Thanks.
<Window x:Class="Surfin.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Surfin"
Background="Black" x:Name="mainWindow"
MinWidth="650" MinHeight="365" Width="650" Height="365">
<!-- Declare the MyVideos class, which belongs to the DataTemplatingLab namespace.-->
<!-- Setting the Directory to the relative path pointing to the Media folder.-->
<!-- Giving this an x:Key. Now controls in this Window can bind to the videos in the Media folder.-->
<Window.Resources>
<MyVideos xmlns="clr-namespace:DataTemplatingLab" Directory="Media" x:Key="vids" />
<DataTemplate x:Key="mainScreenTemplate">
<Border BorderBrush="LimeGreen" BorderThickness="2"
CornerRadius="3" Margin="15">
<Grid>
<!-- Background image if no video is playing. -->
<Image Source="Images\Crystal.jpg" Stretch="Fill"/>
<!-- The video -->
<!-- The Source property of the video is bound to the Source property of the current MyVideo object.-->
<MediaElement Name="mainVideo" Stretch="Fill"
Source="{Binding Path=Source}"/>
</Grid>
</Border>
</DataTemplate>
<DataTemplate x:Key="listBoxTemplate">
<DataTemplate.Resources>
<Style TargetType="DockPanel">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="ToolTipService.ShowDuration" Value="80000"/>
</Style>
</DataTemplate.Resources>
<DockPanel Height="70" Width="160">
<Border Margin="4,5,0,0" Height="50" Width="50">
<Image Source="Images\Preview.png" />
</Border>
<TextBlock Text="{Binding Path=VideoTitle}" VerticalAlignment="Center"
TextBlock.TextTrimming="WordEllipsis" Margin="5,5,0,5"
Foreground="White" FontSize="12" FontFamily="Comic Sans MS">
</TextBlock>
</DockPanel>
</DataTemplate>
<Style x:Key="{x:Type ListBoxItem}" TargetType="ListBoxItem">
<Setter Property="Margin" Value="10,10,10,0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid>
<Rectangle x:Name="GelBackground" RadiusX="9" RadiusY="9"
Opacity="1" Fill="{TemplateBinding Background}"
Stroke="#66ffffff" StrokeThickness="1" />
<Rectangle x:Name="GelShine" RadiusX="6" RadiusY="6"
Opacity="1" Margin="2,2,2,0" VerticalAlignment="top"
Stroke="transparent" Height="15">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#ccffffff" Offset="0" />
<GradientStop Color="transparent" Offset="1" />
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Grid>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard TargetName="GelBackground"
TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<ColorAnimation To="LimeGreen" Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard TargetName="GelBackground"
TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<ColorAnimation Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" Value="RoyalBlue" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<!-- 1) The ListBox and ContentControl bind to the same source. -->
<!-- 2) IsSynchronizedWithCurrentItem set to true. -->
<!-- With the above 2 conditions satisfied, once the DataTemplates are in place,
the ContentControl will display the content of the selected list item.-->
<DockPanel>
<ListBox DockPanel.Dock="Left" Width="200" BorderThickness="0"
ItemsSource="{Binding Source={StaticResource vids}}"
IsSynchronizedWithCurrentItem="True"
ItemTemplate="{StaticResource listBoxTemplate}"
Background="Transparent"/>
<ContentControl Content="{Binding Source={StaticResource vids}}"
ContentTemplate="{StaticResource mainScreenTemplate}"/>
</DockPanel>
</Window>
<Style x:Key="{x:Type Button}" TargetType="Button">
<Setter Property="Margin" Value="10,10,10,0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Rectangle x:Name="GelBackground" RadiusX="9" RadiusY="9"
Opacity="1" Fill="{TemplateBinding Background}"
Stroke="#66ffffff" StrokeThickness="1" />
<Rectangle x:Name="GelShine" RadiusX="6" RadiusY="6"
Opacity="1" Margin="2,2,2,0" VerticalAlignment="top"
Stroke="transparent" Height="15">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#ccffffff" Offset="0" />
<GradientStop Color="transparent" Offset="1" />
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Grid>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard TargetName="GelBackground"
TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<ColorAnimation To="LimeGreen" Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard TargetName="GelBackground"
TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<ColorAnimation Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="RoyalBlue" />
</Trigger>
</Style.Triggers>
</Style>
Something like this. Hope this helps.

Silverlight Bind VisualState to different Targets

I'm using the following border style:
<!-- Border Style -->
<Style TargetType="Border">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5, 1" StartPoint="0.5 ,0" MappingMode="RelativeToBoundingBox">
<GradientStop Color="#00000000" Offset="0" />
<GradientStop Color="#FFFFFEBB" Offset="0.116"/>
<GradientStop Color="#FFFFFEBB" Offset="0.897"/>
<GradientStop Color="#00000000" Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Opacity" Value="0"/>
<Setter Property="OpacityMask">
<Setter.Value>
<LinearGradientBrush EndPoint="1.0 ,0.5" StartPoint="0.0 ,0.5" MappingMode="RelativeToBoundingBox">
<GradientStop/>
<GradientStop Color="#FF000000" Offset="0.1"/>
<GradientStop Color="#FF000000" Offset="0.9"/>
<GradientStop Color="#00000000" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="RenderTransform">
<Setter.Value>
<CompositeTransform ScaleX="1.03" ScaleY="1.01"/>
</Setter.Value>
</Setter>
</Style>
There are three Borders in my application. I want to animate the opacity of the border when the mouse cursor is entering the border. In order to do that, I'm using a VisualState:
<VisualState x:Name="MouseOverState">
<Storyboard>
<DoubleAnimation To="1" Storyboard.TargetProperty="(UIElement.Opacity)" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
Do I need to define three different VisualStates and set the Storyboard.TargetName property? Or is there a way to use the same VisualState for many objects?
PS:
I know that there is a TargetName and TargetObject Property in the GoToStateAction, but I can't get it to work:
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<ei:GoToStateAction StateName="MouseOverState" TargetName="border0"/>
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeave">
<ei:GoToStateAction StateName="DefaultState" TargetName="border0"/>
</i:EventTrigger>
</i:Interaction.Triggers>
I'd be inclined to create a custom control deriving from the ContentControl.
In themes\generic.xaml
<Style TargetType="local:MyBorder">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5, 1" StartPoint="0.5 ,0" MappingMode="RelativeToBoundingBox">
<GradientStop Color="#00000000" Offset="0" />
<GradientStop Color="#FFFFFEBB" Offset="0.116"/>
<GradientStop Color="#FFFFFEBB" Offset="0.897"/>
<GradientStop Color="#00000000" Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="OpacityMask">
<Setter.Value>
<LinearGradientBrush EndPoint="1.0 ,0.5" StartPoint="0.0 ,0.5" MappingMode="RelativeToBoundingBox">
<GradientStop/>
<GradientStop Color="#FF000000" Offset="0.1"/>
<GradientStop Color="#FF000000" Offset="0.9"/>
<GradientStop Color="#00000000" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="RenderTransform">
<Setter.Value>
<CompositeTransform ScaleX="1.03" ScaleY="1.01"/>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="#FF000000"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MyBorder">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Opacity="0"
>
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name="CommonStates">
<vsm:VisualState x:Name="Normal"/>
<vsm:VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation To="1" Storyboard.TargetProperty="(UIElement.Opacity)" />
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup >
</vsm:VisualStateManager>
<ContentPresenter
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Cursor="{TemplateBinding Cursor}"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You just need to add the MouseEnter MouseLeave set the visual state of the control accordingly.
Now you can simply drop local:MyBorder where you need one of these borders.

WPF progressbar style is blocky?

I'm using an indeterminate progressbar in my application and I get this bad animation of a series of blocks running horizontally. Isn't there a better style available like vista or windows 7?
Your progress bar has a style that corresponds to your current windows theme. If you run your application on Windows 7 with an Aero theme your progress bar will look accordingly.
If you want it to look always the same (no matter what windows theme is selected) you will need to define your own style for the progress bar.
Here is the style from the Aero Normal Color theme:
<LinearGradientBrush x:Key="ProgressBarBorderBrush"
EndPoint="0,1"
StartPoint="0,0">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#B2B2B2"
Offset="0"/>
<GradientStop Color="#8C8C8C"
Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarBackground"
EndPoint="1,0"
StartPoint="0,0">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#BABABA"
Offset="0"/>
<GradientStop Color="#C7C7C7"
Offset="0.5"/>
<GradientStop Color="#BABABA"
Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarTopHighlight"
StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#80FFFFFF"
Offset="0.05"/>
<GradientStop Color="#00FFFFFF"
Offset="0.25"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarGlassyHighlight"
StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#50FFFFFF"
Offset="0.5385"/>
<GradientStop Color="#00FFFFFF"
Offset="0.5385"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorGlassyHighlight"
StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#90FFFFFF"
Offset="0.5385"/>
<GradientStop Color="#00FFFFFF"
Offset="0.5385"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<RadialGradientBrush x:Key="ProgressBarIndicatorLightingEffectLeft"
RadiusX="1"
RadiusY="1"
RelativeTransform="1,0,0,1,0.5,0.5">
<RadialGradientBrush.GradientStops>
<GradientStop Color="#60FFFFC4"
Offset="0"/>
<GradientStop Color="#00FFFFC4"
Offset="1"/>
</RadialGradientBrush.GradientStops>
</RadialGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorLightingEffect"
StartPoint="0,1"
EndPoint="0,0">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#60FFFFC4"
Offset="0"/>
<GradientStop Color="#00FFFFC4"
Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<RadialGradientBrush x:Key="ProgressBarIndicatorLightingEffectRight"
RadiusX="1"
RadiusY="1"
RelativeTransform="1,0,0,1,-0.5,0.5">
<RadialGradientBrush.GradientStops>
<GradientStop Color="#60FFFFC4"
Offset="0"/>
<GradientStop Color="#00FFFFC4"
Offset="1"/>
</RadialGradientBrush.GradientStops>
</RadialGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorDarkEdgeLeft"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#0C000000"
Offset="0"/>
<GradientStop Color="#20000000"
Offset="0.3"/>
<GradientStop Color="#00000000"
Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorDarkEdgeRight"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#00000000"
Offset="0"/>
<GradientStop Color="#20000000"
Offset="0.7"/>
<GradientStop Color="#0C000000"
Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#00FFFFFF"
Offset="0"/>
<GradientStop Color="#60FFFFFF"
Offset="0.4"/>
<GradientStop Color="#60FFFFFF"
Offset="0.6"/>
<GradientStop Color="#00FFFFFF"
Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<Style x:Key="{x:Type ProgressBar}"
TargetType="{x:Type ProgressBar}">
<Setter Property="Foreground"
Value="#01D328"/>
<Setter Property="Background"
Value="{StaticResource ProgressBarBackground}"/>
<Setter Property="BorderBrush"
Value="{StaticResource ProgressBarBorderBrush}"/>
<Setter Property="BorderThickness"
Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Grid Name="TemplateRoot"
SnapsToDevicePixels="true">
<Rectangle Fill="{TemplateBinding Background}"
RadiusX="2"
RadiusY="2"/>
<Border Background="{StaticResource ProgressBarGlassyHighlight}"
Margin="1"
CornerRadius="2"/>
<Border BorderBrush="#80FFFFFF"
Background="{StaticResource ProgressBarTopHighlight}"
BorderThickness="1,0,1,1"
Margin="1"/>
<Rectangle Name="PART_Track"
Margin="1"/>
<Decorator x:Name="PART_Indicator"
HorizontalAlignment="Left"
Margin="1">
<Grid Name="Foreground">
<Rectangle x:Name="Indicator"
Fill="{TemplateBinding Foreground}"/>
<Grid x:Name="Animation" ClipToBounds="true">
<Rectangle x:Name="PART_GlowRect" Width="100"
Fill="{StaticResource ProgressBarIndicatorAnimatedFill}"
Margin="-100,0,0,0"
HorizontalAlignment="Left">
</Rectangle>
</Grid>
<Grid x:Name="Overlay">
<Grid.ColumnDefinitions>
<ColumnDefinition MaxWidth="15"/>
<ColumnDefinition Width="0.1*"/>
<ColumnDefinition MaxWidth="15"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Rectangle x:Name="LeftDark"
Grid.RowSpan="2"
Fill="{StaticResource ProgressBarIndicatorDarkEdgeLeft}"
RadiusX="1"
RadiusY="1"
Margin="1,1,0,1"/>
<Rectangle x:Name="RightDark"
Grid.RowSpan="2"
Grid.Column="2"
RadiusX="1"
RadiusY="1"
Fill="{StaticResource ProgressBarIndicatorDarkEdgeRight}"
Margin="0,1,1,1"/>
<Rectangle x:Name="LeftLight"
Grid.Column="0"
Grid.Row="2"
Fill="{StaticResource ProgressBarIndicatorLightingEffectLeft}"/>
<Rectangle x:Name="CenterLight"
Grid.Column="1"
Grid.Row="2"
Fill="{StaticResource ProgressBarIndicatorLightingEffect}"/>
<Rectangle x:Name="RightLight"
Grid.Column="2"
Grid.Row="2"
Fill="{StaticResource ProgressBarIndicatorLightingEffectRight}"/>
<Border x:Name="Highlight1"
Grid.RowSpan="2"
Grid.ColumnSpan="3"
Background="{StaticResource ProgressBarIndicatorGlassyHighlight}"/>
<Border x:Name="Highlight2"
Grid.RowSpan="2"
Grid.ColumnSpan="3"
Background="{StaticResource ProgressBarTopHighlight}"/>
</Grid>
</Grid>
</Decorator>
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="2"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Orientation"
Value="Vertical">
<Setter TargetName="TemplateRoot"
Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="-90"/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsIndeterminate"
Value="true">
<Setter TargetName="LeftDark"
Property="Visibility"
Value="Collapsed"/>
<Setter TargetName="RightDark"
Property="Visibility"
Value="Collapsed"/>
<Setter TargetName="LeftLight"
Property="Visibility"
Value="Collapsed"/>
<Setter TargetName="CenterLight"
Property="Visibility"
Value="Collapsed"/>
<Setter TargetName="RightLight"
Property="Visibility"
Value="Collapsed"/>
<Setter TargetName="Indicator"
Property="Visibility"
Value="Collapsed"/>
</Trigger>
<Trigger Property="IsIndeterminate"
Value="false">
<Setter TargetName="Animation"
Property="Background"
Value="#80B5FFA9"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Put this code in the Themes/Generic.xaml file in your application and your progress bars will always have this style.
This is another one... very simple flat progress bar for IsInderminate mode-
<ControlTemplate x:Key="CustomProgressBar" TargetType="ProgressBar" >
<Grid Name="TemplateRoot" SnapsToDevicePixels="True">
<Rectangle RadiusX="2" RadiusY="2" Fill="Transparent" />
<Border CornerRadius="0,0,0,0" Margin="1,1,1,1">
<Border.Background>
<SolidColorBrush Color="Transparent"/>
</Border.Background>
</Border>
<Border BorderThickness="0,0,0,0" BorderBrush="Transparent" Margin="1,1,1,1">
<Border.Background>
<SolidColorBrush Color="Transparent"/>
</Border.Background>
</Border>
<Rectangle Name="PART_Track" Margin="1,1,1,1" />
<Decorator Name="PART_Indicator" Margin="1,1,1,1" HorizontalAlignment="Left">
<Grid Name="Foreground">
<Rectangle Fill="Transparent" Name="Indicator" />
<Grid Name="Animation" ClipToBounds="True">
<Border Name="PART_GlowRect" Width="100" Margin="0,0,0,0" HorizontalAlignment="Left" Background="LightBlue"/>
</Grid>
<Grid Name="Overlay">
</Grid>
</Grid>
</Decorator>
<Border BorderThickness="0" CornerRadius="0,0,0,0" BorderBrush="Transparent" />
</Grid>
</ControlTemplate>
This is a custom progress bar I made from Suneet's example, but with IsIndeterminate animation working in .NET 3.5 :
<Style x:Key="{x:Type ProgressBar}" TargetType="{x:Type ProgressBar}">
<Setter Property="Foreground" Value="#54bdcd"/>
<Setter Property="Background" Value="#000000"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Grid Name="TemplateRoot" SnapsToDevicePixels="true">
<Rectangle Fill="{TemplateBinding Background}"/>
<Rectangle Name="PART_Track" Margin="0"/>
<Decorator x:Name="PART_Indicator" HorizontalAlignment="Left" Margin="0">
<Grid Name="Foreground">
<Rectangle Fill="{TemplateBinding Foreground}" Name="Indicator" />
<Grid Name="Animation" ClipToBounds="True">
<Border Name="PART_GlowRect" Margin="0,0,0,0" HorizontalAlignment="Left" Background="{TemplateBinding Foreground}"/>
</Grid>
<Grid Name="Overlay">
</Grid>
</Grid>
</Decorator>
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsIndeterminate" Value="true">
<Setter TargetName="Indicator" Property="Fill" Value="Transparent" />
<Setter TargetName="PART_GlowRect" Property="Width" Value="100" />
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation
Storyboard.TargetName="PART_GlowRect"
Storyboard.TargetProperty="Margin"
From="-50,0,0,0" To="400,0,0,0" Duration="0:0:2"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This is kinda a hack because I move the indeterminate bar back and forth by changing its marginleft value, but in my case it was affordable because my progress bar was a fixed width.
If you have a better idea, feel free to change the storyboard part.
This page helped me a lot.
Here is another one that supports normal and intermediate mode:
<Style TargetType="{x:Type ProgressBar}">
<Setter Property="Foreground" Value="#1BA1E2"/>
<Setter Property="Background" Value="#EEEEEE"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Grid Name="TemplateRoot" SnapsToDevicePixels="true">
<Rectangle Fill="{TemplateBinding Background}"/>
<Rectangle Name="PART_Track" Margin="0"/>
<Decorator x:Name="PART_Indicator" HorizontalAlignment="Left" Margin="0">
<Grid Name="Foreground">
<Rectangle Fill="{TemplateBinding Foreground}" Name="Indicator" />
<Grid x:Name="Animation" ClipToBounds="true" Visibility="Hidden">
<Rectangle Fill="{TemplateBinding Background}" Name="HiderPre" Margin="0,0,50,0">
<Rectangle.RenderTransform>
<ScaleTransform x:Name="HiderPreTransform" ScaleX="0"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Fill="{TemplateBinding Background}" Name="HiderPost" RenderTransformOrigin="1, 0" Margin="50,0,0,0">
<Rectangle.RenderTransform>
<ScaleTransform x:Name="HiderPostTransform" ScaleX="1" />
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
<Grid Name="Overlay">
</Grid>
</Grid>
</Decorator>
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsIndeterminate" Value="true">
<Setter TargetName="Animation" Property="Visibility" Value="Visible" />
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation
Storyboard.TargetName="HiderPreTransform"
Storyboard.TargetProperty="(ScaleTransform.ScaleX)"
To="1"
Duration="0:00:4" AutoReverse="True"/>
<DoubleAnimation
Storyboard.TargetName="HiderPostTransform"
Storyboard.TargetProperty="(ScaleTransform.ScaleX)"
To="0"
Duration="0:00:4" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="Gray" />
</Trigger>
</Style.Triggers>
</Style>
The simplest approach I could find is based heavily on https://stackoverflow.com/a/19737148/3195477 but even more simplified.
This produces a simple flat look:
<ProgressBar>
<ProgressBar.Template>
<ControlTemplate TargetType="ProgressBar">
<Border
BorderBrush="Black"
BorderThickness="1"
Background="LightGray"
>
<Grid x:Name="PART_Track">
<Rectangle
x:Name="PART_Indicator"
HorizontalAlignment="Left"
Fill="Blue"
/>
</Grid>
</Border>
</ControlTemplate>
</ProgressBar.Template>
</ProgressBar>
The "trick" is to just minimally replace the named parts with very simple alternatives. You don't necessarily need complex gradients etc. to improve on the default appearance, although that's a matter of opinion.

Resources