How to style the slider control in WPF?

34,629

Solution 1

The Slider Control has many parts Thumb, RepeatButtons and a Track. It is one of those controls that have named elements, like PART_Track, referenced by the code-behind for it to work correctly. A good starting point is to use Blend to help you out.

Start a new project (or create a new window). In the XAML window add the following:

<ScrollBar/>

Then in design window of Blend right-click on the control and select "Edit control parts (Template)\Edit a Copy...". This will reverse engineer the standard control template. This can then be edited.

The Blend output is this:-

    <LinearGradientBrush x:Key="VerticalScrollBarPageButtonNormal" EndPoint="1, 0" StartPoint="0, 0">
        <GradientStop Color="#EEEDE5" Offset="0"/>
        <GradientStop Color="#EEEDE5" Offset="0.05"/>
        <GradientStop Color="#F3F1EC" Offset="0.06"/>
        <GradientStop Color="#FEFEFE" Offset="0.94"/>
        <GradientStop Color="#EEEDE5" Offset="0.95"/>
        <GradientStop Color="#EEEDE5" Offset="1"/>
    </LinearGradientBrush>
    <Style x:Key="ScrollBarButton" TargetType="{x:Type RepeatButton}">
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="Focusable" Value="false"/>
        <Setter Property="IsTabStop" Value="false"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RepeatButton}">
                    <Microsoft_Windows_Themes:ScrollChrome SnapsToDevicePixels="true" x:Name="Chrome" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" Microsoft_Windows_Themes:ScrollChrome.ScrollGlyph="{TemplateBinding Microsoft_Windows_Themes:ScrollChrome.ScrollGlyph}" ThemeColor="Metallic"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <LinearGradientBrush x:Key="VerticalScrollBarPageButtonPressed" EndPoint="1, 0" StartPoint="0, 0">
        <GradientStop Color="#D7D5C2" Offset="0"/>
        <GradientStop Color="#D7D5C2" Offset="0.05"/>
        <GradientStop Color="#E3DED3" Offset="0.06"/>
        <GradientStop Color="#FDFDF6" Offset="0.94"/>
        <GradientStop Color="#D7D5C2" Offset="0.95"/>
        <GradientStop Color="#D7D5C2" Offset="1"/>
    </LinearGradientBrush>
    <LinearGradientBrush x:Key="VerticalScrollBarPageButtonDisabled" EndPoint="1, 0" StartPoint="0, 0">
        <GradientStop Color="#EEEDE5" Offset="0"/>
        <GradientStop Color="#EEEDE5" Offset="0.05"/>
        <GradientStop Color="#F3F1EC" Offset="0.06"/>
        <GradientStop Color="#FEFEFE" Offset="0.94"/>
        <GradientStop Color="#EEEDE5" Offset="0.95"/>
        <GradientStop Color="#EEEDE5" Offset="1"/>
    </LinearGradientBrush>
    <Style x:Key="VerticalScrollBarPageButton" TargetType="{x:Type RepeatButton}">
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Focusable" Value="false"/>
        <Setter Property="IsTabStop" Value="false"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RepeatButton}">
                    <Rectangle x:Name="Bg" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Fill="{TemplateBinding Background}"/>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsPressed" Value="true">
                            <Setter Property="Fill" TargetName="Bg" Value="{StaticResource VerticalScrollBarPageButtonPressed}"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Fill" TargetName="Bg" Value="{StaticResource VerticalScrollBarPageButtonDisabled}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="ScrollBarThumb" TargetType="{x:Type Thumb}">
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="IsTabStop" Value="false"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Thumb}">
                    <Microsoft_Windows_Themes:ScrollChrome SnapsToDevicePixels="true" x:Name="Chrome" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsDragging}" Microsoft_Windows_Themes:ScrollChrome.ScrollGlyph="{TemplateBinding Microsoft_Windows_Themes:ScrollChrome.ScrollGlyph}" ThemeColor="Metallic"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <LinearGradientBrush x:Key="HorizontalScrollBarPageButtonNormal" EndPoint="0, 1" StartPoint="0, 0">
        <GradientStop Color="#EEEDE5" Offset="0"/>
        <GradientStop Color="#EEEDE5" Offset="0.05"/>
        <GradientStop Color="#F3F1EC" Offset="0.06"/>
        <GradientStop Color="#FEFEFE" Offset="0.94"/>
        <GradientStop Color="#EEEDE5" Offset="0.95"/>
        <GradientStop Color="#EEEDE5" Offset="1"/>
    </LinearGradientBrush>
    <LinearGradientBrush x:Key="HorizontalScrollBarPageButtonPressed" EndPoint="0, 1" StartPoint="0, 0">
        <GradientStop Color="#D7D5C2" Offset="0"/>
        <GradientStop Color="#D7D5C2" Offset="0.05"/>
        <GradientStop Color="#E3DED3" Offset="0.06"/>
        <GradientStop Color="#FDFDF6" Offset="0.94"/>
        <GradientStop Color="#D7D5C2" Offset="0.95"/>
        <GradientStop Color="#D7D5C2" Offset="1"/>
    </LinearGradientBrush>
    <LinearGradientBrush x:Key="HorizontalScrollBarPageButtonDisabled" EndPoint="0, 1" StartPoint="0, 0">
        <GradientStop Color="#EEEDE5" Offset="0"/>
        <GradientStop Color="#EEEDE5" Offset="0.05"/>
        <GradientStop Color="#F3F1EC" Offset="0.06"/>
        <GradientStop Color="#FEFEFE" Offset="0.94"/>
        <GradientStop Color="#EEEDE5" Offset="0.95"/>
        <GradientStop Color="#EEEDE5" Offset="1"/>
    </LinearGradientBrush>
    <Style x:Key="HorizontalScrollBarPageButton" TargetType="{x:Type RepeatButton}">
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Focusable" Value="false"/>
        <Setter Property="IsTabStop" Value="false"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RepeatButton}">
                    <Rectangle x:Name="Bg" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Fill="{TemplateBinding Background}"/>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsPressed" Value="true">
                            <Setter Property="Fill" TargetName="Bg" Value="{StaticResource HorizontalScrollBarPageButtonPressed}"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Fill" TargetName="Bg" Value="{StaticResource HorizontalScrollBarPageButtonDisabled}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="ScrollBarStyle1" TargetType="{x:Type ScrollBar}">
        <Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/>
        <Setter Property="Stylus.IsFlicksEnabled" Value="false"/>
        <Setter Property="Background" Value="{StaticResource VerticalScrollBarPageButtonNormal}"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="Width" Value="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"/>
        <Setter Property="MinWidth" Value="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ScrollBar}">
                    <Grid SnapsToDevicePixels="true" Background="{TemplateBinding Background}">
                        <Grid.RowDefinitions>
                            <RowDefinition MaxHeight="{DynamicResource {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
                            <RowDefinition Height="0.00001*"/>
                            <RowDefinition MaxHeight="{DynamicResource {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
                        </Grid.RowDefinitions>
                        <RepeatButton Style="{StaticResource ScrollBarButton}" Command="{x:Static ScrollBar.LineUpCommand}" Microsoft_Windows_Themes:ScrollChrome.ScrollGlyph="UpArrow"/>
                        <Track x:Name="PART_Track" Grid.Row="1" IsDirectionReversed="true">
                            <Track.Thumb>
                                <Thumb Style="{StaticResource ScrollBarThumb}" Microsoft_Windows_Themes:ScrollChrome.ScrollGlyph="VerticalGripper"/>
                            </Track.Thumb>
                            <Track.IncreaseRepeatButton>
                                <RepeatButton Style="{StaticResource VerticalScrollBarPageButton}" Command="{x:Static ScrollBar.PageDownCommand}"/>
                            </Track.IncreaseRepeatButton>
                            <Track.DecreaseRepeatButton>
                                <RepeatButton Style="{StaticResource VerticalScrollBarPageButton}" Command="{x:Static ScrollBar.PageUpCommand}"/>
                            </Track.DecreaseRepeatButton>
                        </Track>
                        <RepeatButton Style="{StaticResource ScrollBarButton}" Command="{x:Static ScrollBar.LineDownCommand}" Grid.Row="2" Microsoft_Windows_Themes:ScrollChrome.ScrollGlyph="DownArrow"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="Orientation" Value="Horizontal">
                <Setter Property="Width" Value="Auto"/>
                <Setter Property="MinWidth" Value="0"/>
                <Setter Property="Background" Value="{StaticResource HorizontalScrollBarPageButtonNormal}"/>
                <Setter Property="Height" Value="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarHeightKey}}"/>
                <Setter Property="MinHeight" Value="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarHeightKey}}"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ScrollBar}">
                            <Grid SnapsToDevicePixels="true" Background="{TemplateBinding Background}">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition MaxWidth="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarButtonWidthKey}}"/>
                                    <ColumnDefinition Width="0.00001*"/>
                                    <ColumnDefinition MaxWidth="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarButtonWidthKey}}"/>
                                </Grid.ColumnDefinitions>
                                <RepeatButton Style="{StaticResource ScrollBarButton}" Command="{x:Static ScrollBar.LineLeftCommand}" Microsoft_Windows_Themes:ScrollChrome.ScrollGlyph="LeftArrow"/>
                                <Track x:Name="PART_Track" Grid.Column="1">
                                    <Track.Thumb>
                                        <Thumb Style="{StaticResource ScrollBarThumb}" Microsoft_Windows_Themes:ScrollChrome.ScrollGlyph="HorizontalGripper"/>
                                    </Track.Thumb>
                                    <Track.IncreaseRepeatButton>
                                        <RepeatButton Style="{StaticResource HorizontalScrollBarPageButton}" Command="{x:Static ScrollBar.PageRightCommand}"/>
                                    </Track.IncreaseRepeatButton>
                                    <Track.DecreaseRepeatButton>
                                        <RepeatButton Style="{StaticResource HorizontalScrollBarPageButton}" Command="{x:Static ScrollBar.PageLeftCommand}"/>
                                    </Track.DecreaseRepeatButton>
                                </Track>
                                <RepeatButton Style="{StaticResource ScrollBarButton}" Command="{x:Static ScrollBar.LineRightCommand}" Grid.Column="2" Microsoft_Windows_Themes:ScrollChrome.ScrollGlyph="RightArrow"/>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>

The namespace used for this was this (add to top of file):-

  xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Luna"

You can then obviously alter the generated style to your heart's content

You would need to either programmatically find the scrollbar embedded in the control or apply the style to all scrollbars in the scope by altering the style definition, so:-

  <Style x:Key="ScrollBarStyle1" TargetType="{x:Type ScrollBar}">
    ...
  </Style>

becomes

  <Style TargetType="{x:Type ScrollBar}">
    ...
  </Style>

So that it will be applied to all scroll bars in the region defined by the style.

Solution 2

You also might want to take a look at snoop and style snooper

Solution 3

You will have to create a control template to restyle the part of the control you want.

Have a look at this MSDN article and this article which should help you.

Solution 4

A nice MSDN article giving control templates for all the WPF controls is available here:

http://msdn.microsoft.com/en-us/library/aa970773.aspx

Bear in mind that these control templates generate the same control visually (i.e.: these are the control templates that WPF uses). But it's a good starting point for customizing your controls' Visual Trees.

Solution 5

Here's a simple and quick way:

<Slider ...>
    <Slider.LayoutTransform>
         <ScaleTransform CenterX="0" CenterY="0" ScaleX="1" ScaleY="0.5"/>
    </Slider.LayoutTransform>
</Slider>

This is not EXACTLY 8 pixels but you can play a bit with the ScaleY property until you get the size you want.

Share:
34,629
Sander Versluys
Author by

Sander Versluys

I may not have gone where I intended to go, but I think I have ended up where I needed to be. - Douglas Adams about.me/sanderversluys

Updated on January 10, 2020

Comments

  • Sander Versluys
    Sander Versluys over 4 years

    I want to style the slider control so that the height of the draggable thumb is set to 8 pixels.

    What is the simplest way to do this in WPF?

    <Slider>
        <Slider.Style>
            <!-- which xaml here? -->
        </Slider.style>
    </Slider>