Click here to Skip to main content
15,886,809 members
Articles / Desktop Programming / WPF

WPFSpark: 6 of n: FluidProgressBar

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
19 Jan 2012Ms-PL4 min read 45.2K   1.5K   20  
A Windows Phone style indeterminate ProgressBar in WPF.
<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">

    <!-- ToggleSwitch Template -->
    <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>

        <!-- Outermost border of the ToggleSwitch -->
        <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>
                <!-- PART_Content -->
                <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>
                        <!-- Checked State -->
                        <!-- Background displayed when the ToggleSwitch is in the Checked State -->
                        <Border x:Name="PART_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>
                        <!-- Text which is displayed when the ToggleSwitch is in the Checked State -->
                        <TextBlock x:Name="PART_CheckedContent"
                                   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.Effect>
                                <DropShadowEffect BlurRadius="4"
                                                  ShadowDepth="1"
                                                  Color="Black"
                                                  Opacity="0.7"
                                                  Direction="-88"></DropShadowEffect>
                            </TextBlock.Effect>
                        </TextBlock>

                        <!-- Unchecked State -->
                        <!-- Background displayed when the ToggleSwitch is in the Unchecked State -->
                        <Border x:Name="PART_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>
                        <!-- Text which is displayed when the ToggleSwitch is in the Unchecked State -->
                        <TextBlock x:Name="PART_UncheckedContent"
                                   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.Effect>
                                <DropShadowEffect BlurRadius="4"
                                                  ShadowDepth="1"
                                                  Color="Black"
                                                  Opacity="0.7"
                                                  Direction="-88"></DropShadowEffect>
                            </TextBlock.Effect>
                        </TextBlock>

                        <!-- ToggleSwitch Thumb -->
                        <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>
                                <Border x:Name="DisabledBorder"
                                        Grid.Column="0"
                                        Grid.ColumnSpan="5"
                                        BorderThickness="0"
                                        Margin="0"
                                        CornerRadius="0"
                                        Background="White"
                                        Opacity="0.5"
                                        Visibility="Hidden">
                                </Border>
                            </Grid>
                        </wpfspark:ClipBorder>
                    </Grid>
                </Border>
            </Grid>
        </wpfspark:ClipBorder>

        <ControlTemplate.Triggers>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="ToggleButton.IsChecked"
                               Value="true"></Condition>
                    <Condition Property="IsCheckedLeft"
                               Value="true"></Condition>
                </MultiTrigger.Conditions>
                <MultiTrigger.Setters>
                    <Setter Property="Grid.Column"
                            TargetName="PART_ContentBorder"
                            Value="{Binding Path=TargetColumnInternal, RelativeSource={RelativeSource AncestorType={x:Type wpfspark:ToggleSwitch}}}" />
                </MultiTrigger.Setters>
            </MultiTrigger>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="ToggleButton.IsChecked"
                               Value="false"></Condition>
                    <Condition Property="IsCheckedLeft"
                               Value="false"></Condition>
                </MultiTrigger.Conditions>
                <MultiTrigger.Setters>
                    <Setter Property="Grid.Column"
                            TargetName="PART_ContentBorder"
                            Value="{Binding Path=TargetColumnInternal, RelativeSource={RelativeSource AncestorType={x:Type wpfspark:ToggleSwitch}}}" />
                </MultiTrigger.Setters>
            </MultiTrigger>

            <Trigger Property="IsEnabled"
                     Value="false">
                <Setter Property="Opacity"
                        Value="0.3" />
                <Setter TargetName="PART_UncheckedContent"
                        Property="Foreground"
                        Value="LightGray"></Setter>
                <Setter TargetName="PART_CheckedContent"
                        Property="Foreground"
                        Value="LightGray"></Setter>
                <Setter TargetName="DisabledBorder"
                        Property="Visibility"
                        Value="Visible"></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="FocusVisualStyle"
                Value="{x:Null}" />
        <Setter Property="Template"
                Value="{StaticResource {ComponentResourceKey TypeInTargetAssembly=wpfspark:ToggleSwitch, ResourceId=ToggleSwitchTemplate}}" />
    </Style>

</ResourceDictionary>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
Software Developer
United States United States
An individual with more than a decade of experience in desktop computing and mobile app development primarily on the Microsoft platform. He loves programming in C#, WPF & XAML related technologies.
Current interests include web application development, developing rich user experiences across various platforms and exploring his creative side.

Ratish's personal blog: wpfspark.wordpress.com

Comments and Discussions