×
Namespaces

Variants
Actions
(Difference between revisions)

Retemplate Windows Phone Slider control to show Minimum, Maximum and Value values

From Nokia Developer Wiki
Jump to: navigation, search
andrejt (Talk | contribs)
m (Andrejt -)
andrejt (Talk | contribs)
m (Andrejt -)
Line 1: Line 1:
[[Category:Windows Phone 8]][[Category:XAML]][[Category:UI on Windows Phone]][[Category:Code Snippet]][[Category:How To]]
+
[[Category:Windows Phone 8]][[Category:XAML]][[Category:UI on Windows Phone]][[Category:Code Snippet]][[Category:How To]][[Category:Windows Phone]]
 
{{Abstract|This article explains how to change style of the default '''Windows Phone 8 Slider control''' to show '''Minimum''', '''Maximum''' and current '''Value''' property values }}
 
{{Abstract|This article explains how to change style of the default '''Windows Phone 8 Slider control''' to show '''Minimum''', '''Maximum''' and current '''Value''' property values }}
  

Revision as of 13:24, 10 December 2013

This article explains how to change style of the default Windows Phone 8 Slider control to show Minimum, Maximum and current Value property values

WP Metro Icon UI.png
SignpostIcon XAML 40.png
WP Metro Icon WP8.png
Article Metadata
Tested with
SDK: Windows Phone 8.0 SDK
Devices(s): Lumia 920
Compatibility
Platform(s):
Windows Phone 8
Article
Created: andrejt (10 Dec 2013)
Last edited: andrejt (10 Dec 2013)

Contents

Introduction

The Slider control in Windows Phone controls library lets user change a value in a certain range, but doesn't provide her with exact value she'd chosen, nor the range limits. Some examples of where this would be useful is a volume slider control (value of 75 in a range 0-100, Timespan (minutes) selector (30 in a range 10-45), etc. This article is using the simplest form of changing the default Slider template to decorate Slider control to show those values.

What we want our slider to look like

The default Slider template

The default Slider template is as follows (when edited in Visual Studio or Blend):

  1. <Style x:Key="SliderStyle" TargetType="Slider">
  2.     <Setter Property="BorderThickness" Value="0"/>
  3.     <Setter Property="BorderBrush" Value="Transparent"/>
  4.     <Setter Property="Maximum" Value="10"/>
  5.     <Setter Property="Minimum" Value="0"/>
  6.     <Setter Property="Value" Value="0"/>
  7.     <Setter Property="Background" Value="{StaticResource PhoneChromeBrush}"/>
  8.     <Setter Property="Foreground" Value="{StaticResource PhoneAccentBrush}"/>
  9.     <Setter Property="Template">
  10.         <Setter.Value>
  11.             <ControlTemplate TargetType="Slider">
  12.                 <Grid Background="Transparent">
  13.                     <VisualStateManager.VisualStateGroups>
  14.                         <VisualStateGroup x:Name="CommonStates">
  15.                             <VisualState x:Name="Normal"/>
  16.                             <VisualState x:Name="MouseOver"/>
  17.                             <VisualState x:Name="Disabled">
  18.                                 <Storyboard>
  19.                                     <DoubleAnimation Duration="0" To="0.1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="HorizontalTrack"/>
  20.                                     <DoubleAnimation Duration="0" To="0.1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="VerticalTrack"/>
  21.                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="HorizontalFill">
  22.                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
  23.                                     </ObjectAnimationUsingKeyFrames>
  24.                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="VerticalFill">
  25.                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
  26.                                     </ObjectAnimationUsingKeyFrames>
  27.                                 </Storyboard>
  28.                             </VisualState>
  29.                         </VisualStateGroup>
  30.                     </VisualStateManager.VisualStateGroups>
  31.                     <Grid x:Name="HorizontalTemplate" Margin="{StaticResource PhoneHorizontalMargin}">
  32.                         <Rectangle x:Name="HorizontalTrack" Fill="{TemplateBinding Background}" Height="12" IsHitTestVisible="False" Margin="0,22,0,50"/>
  33.                         <Rectangle x:Name="HorizontalFill" Fill="{TemplateBinding Foreground}" Height="12" IsHitTestVisible="False" Margin="0,22,0,50">
  34.                             <Rectangle.Clip>
  35.                                 <RectangleGeometry Rect="0, 0, 6, 12"/>
  36.                             </Rectangle.Clip>
  37.                         </Rectangle>
  38.                         <Rectangle x:Name="HorizontalCenterElement" Fill="{StaticResource PhoneForegroundBrush}" HorizontalAlignment="Left" Height="24" Margin="0,16,0,44" Width="12">
  39.                             <Rectangle.RenderTransform>
  40.                                 <TranslateTransform/>
  41.                             </Rectangle.RenderTransform>
  42.                         </Rectangle>
  43.                     </Grid>
  44.                     <Grid x:Name="VerticalTemplate" Margin="{StaticResource PhoneVerticalMargin}">
  45.                         <Rectangle x:Name="VerticalTrack" Fill="{TemplateBinding Background}" IsHitTestVisible="False" Margin="18,0,18,0" Width="12"/>
  46.                         <Rectangle x:Name="VerticalFill" Fill="{TemplateBinding Foreground}" IsHitTestVisible="False" Margin="18,0,18,0" Width="12">
  47.                             <Rectangle.Clip>
  48.                                 <RectangleGeometry Rect="0, 0, 12, 6"/>
  49.                             </Rectangle.Clip>
  50.                         </Rectangle>
  51.                         <Rectangle x:Name="VerticalCenterElement" Fill="{StaticResource PhoneForegroundBrush}" Height="12" Margin="12,0,12,0" VerticalAlignment="Top" Width="24">
  52.                             <Rectangle.RenderTransform>
  53.                                 <TranslateTransform/>
  54.                             </Rectangle.RenderTransform>
  55.                         </Rectangle>
  56.                     </Grid>
  57.                 </Grid>
  58.             </ControlTemplate>
  59.         </Setter.Value>
  60.     </Setter>
  61. </Style>

Making changes

We want to edit the template to include 3 TextBlocks that would display the wanted values. As seen in the above template, Slider control provides two separate templates, for horizontal and vertical orientation. As horizontal orientation is more common, this article will focus on changing horizontal template. If you need a solution for vertical template as well, please comment below.

Step 1: Adding Minimum and Maximum labels

Minimum and Maximum labels would be displayed on top of the Slider bar, so let's split the Grid in two rows and add two TextBlocks in the second row:

  1. <Grid x:Name="HorizontalTemplate" Margin="{StaticResource PhoneHorizontalMargin}">
  2.   <Grid.RowDefinitions>
  3.     <RowDefinition Height="Auto"/>
  4.     <RowDefinition Height="Auto"/>
  5.   </Grid.RowDefinitions>
  6.   <TextBlock Grid.Row="1" Text="{Binding Minimum, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Left" Style="{StaticResource PhoneTextTitle3Style}" Foreground="{StaticResource PhoneSubtleBrush}" Margin="0,-42,0,0" />
  7.   <TextBlock Grid.Row="1" Text="{Binding Maximum, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Right" Style="{StaticResource PhoneTextTitle3Style}" Foreground="{StaticResource PhoneSubtleBrush}" Margin="0,-42,0,0" />

Please observe that the first TextBlock is bound to Minimum and aligned to the left, while the second one is bound to Maximum and aligned to the right.

Step 2: Adding Value label

The second step is slightly more radical: promote the HorizontalCenterElement into a StackPanel (by copying most of the properties to it, leaving Rectangle with formatting properties only) and add a TextBlock, bound to Value property.

The new HorizontalCenterElement should look like this:

<StackPanel x:Name="HorizontalCenterElement" Margin="0,16,0,44" HorizontalAlignment="Left" VerticalAlignment="Bottom">
<TextBlock Text="{Binding Value, RelativeSource={RelativeSource TemplatedParent}, StringFormat=N0}" Style="{StaticResource PhoneTextTitle3Style}" Margin="0,0,0,6" HorizontalAlignment="Left"/>
<Rectangle Fill="{StaticResource PhoneForegroundBrush}" Height="24" Width="12"/>
<StackPanel.RenderTransform>
<TranslateTransform />
</StackPanel.RenderTransform>
</StackPanel>

Because the StackPanel is now higher, the last required step is to find HorizontalTrack and HorizontalFill elements and set their VerticalOrientation properties to Bottom, just so they properly align with the value thumb.

Finalizing the new Slider style

This is basically it. The whole style should now look like this:

<Style x:Key="SliderStyle" TargetType="Slider">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Maximum" Value="10"/>
<Setter Property="Minimum" Value="0"/>
<Setter Property="Value" Value="0"/>
<Setter Property="Background" Value="{StaticResource PhoneChromeBrush}"/>
<Setter Property="Foreground" Value="{StaticResource PhoneAccentBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Slider">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" To="0.1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="HorizontalTrack"/>
<DoubleAnimation Duration="0" To="0.1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="VerticalTrack"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="HorizontalFill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="VerticalFill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Name="HorizontalTemplate" Margin="{StaticResource PhoneHorizontalMargin}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="1" Text="{Binding Minimum, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Left" Style="{StaticResource PhoneTextTitle3Style}" Foreground="{StaticResource PhoneSubtleBrush}" Margin="0,-42,0,0" />
<TextBlock Grid.Row="1" Text="{Binding Maximum, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Right" Style="{StaticResource PhoneTextTitle3Style}" Foreground="{StaticResource PhoneSubtleBrush}" Margin="0,-42,0,0" />
 
<Rectangle x:Name="HorizontalTrack" Fill="{TemplateBinding Background}" Height="12" IsHitTestVisible="False" Margin="0,22,0,50" VerticalAlignment="Bottom"/>
<Rectangle x:Name="HorizontalFill" Fill="{TemplateBinding Foreground}" Height="12" IsHitTestVisible="False" Margin="0,22,0,50" VerticalAlignment="Bottom">
<Rectangle.Clip>
<RectangleGeometry Rect="0, 0, 6, 12"/>
</Rectangle.Clip>
</Rectangle>
<StackPanel x:Name="HorizontalCenterElement" Margin="0,16,0,44" HorizontalAlignment="Left" VerticalAlignment="Bottom">
<TextBlock Text="{Binding Value, RelativeSource={RelativeSource TemplatedParent}, StringFormat=N0}" Style="{StaticResource PhoneTextTitle3Style}" Margin="0,0,0,6" HorizontalAlignment="Left"/>
<Rectangle Fill="{StaticResource PhoneForegroundBrush}" Height="24" Width="12"/>
<StackPanel.RenderTransform>
<TranslateTransform />
</StackPanel.RenderTransform>
</StackPanel>
</Grid>
<Grid x:Name="VerticalTemplate" Margin="{StaticResource PhoneVerticalMargin}">
<Rectangle x:Name="VerticalTrack" Fill="{TemplateBinding Background}" IsHitTestVisible="False" Margin="18,0,18,0" Width="12"/>
<Rectangle x:Name="VerticalFill" Fill="{TemplateBinding Foreground}" IsHitTestVisible="False" Margin="18,0,18,0" Width="12">
<Rectangle.Clip>
<RectangleGeometry Rect="0, 0, 12, 6"/>
</Rectangle.Clip>
</Rectangle>
<Rectangle x:Name="VerticalCenterElement" Fill="{StaticResource PhoneForegroundBrush}" Height="12" Margin="12,0,12,0" VerticalAlignment="Top" Width="24">
<Rectangle.RenderTransform>
<TranslateTransform/>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

These are the basic few steps to show how this is done without even touching Slider control's code. You can explore this further by changing paddings, TextBlock Style, flip labels vertically, etc.

303 page views in the last 30 days.
×