Carlos P
Carlos P

Reputation: 3989

Styling XAML Slider control - how do I stop Thumb background changing on PointerOver?

I'm trying to re-style the Slider control using XAML for a Metro style app - it's supposed to look like a red bus that the user drags along a gray strip, i.e.:

enter image description here

I have extracted the Style using Visual Studio and re-styled the Slider control as below. Unfortunately, whenever I hover the mouse over the slider, the thumb is replaced with a grey rectangle, even though I have specifically removed all the Storyboard items from the VisualState "PointerOver" group.

enter image description here

What have I missed? XAML is below. If I need to modify another template (e.g. Thumb?) then please provide steps as to how to extract this template, since Visual Studio does not seem to be exposing any more control templates to me besides the one below.

    <Style x:Key="BusRouteSliderStyle" TargetType="Slider">
        <Setter Property="Background" Value="{StaticResource SliderTrackBackgroundThemeBrush}"/>
        <Setter Property="BorderBrush" Value="{StaticResource SliderBorderThemeBrush}"/>
        <Setter Property="BorderThickness" Value="{StaticResource SliderBorderThemeThickness}"/>
        <Setter Property="Foreground" Value="{StaticResource SliderTrackDecreaseBackgroundThemeBrush}"/>
        <Setter Property="ManipulationMode" Value="None"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Slider">
                    <Grid Margin="{TemplateBinding Padding}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="Pressed">
                                    <Storyboard>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Disabled">
                                    <Storyboard>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="PointerOver">
                                    <Storyboard>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="FocusStates">
                                <VisualState x:Name="Focused">
                                    <Storyboard>
                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualWhiteHorizontal"/>
                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualBlackHorizontal"/>
                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualWhiteVertical"/>
                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualBlackVertical"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Unfocused"/>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Grid x:Name="HorizontalTemplate" Background="Transparent">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="17"/>
                                <RowDefinition Height="30"/>
                                <RowDefinition Height="32"/>
                            </Grid.RowDefinitions>
                            <Rectangle x:Name="HorizontalTrackRect" Grid.ColumnSpan="3" Fill="LightGray" Grid.Row="1"
                                       Height="10" VerticalAlignment="Bottom"/>
                            <Rectangle x:Name="HorizontalDecreaseRect" Height="0" />
                            <TickBar x:Name="TopTickBar" Grid.ColumnSpan="3" Fill="{StaticResource SliderTickmarkOutsideBackgroundThemeBrush}" Height="{StaticResource SliderOutsideTickBarThemeHeight}" Margin="0,0,0,2" Visibility="Collapsed" VerticalAlignment="Bottom"/>
                            <TickBar x:Name="HorizontalInlineTickBar" Grid.ColumnSpan="3" Fill="{StaticResource SliderTickMarkInlineBackgroundThemeBrush}" Height="{StaticResource SliderTrackThemeHeight}" Grid.Row="1" Visibility="Collapsed"/>
                            <TickBar x:Name="BottomTickBar" Grid.ColumnSpan="3" Fill="{StaticResource SliderTickmarkOutsideBackgroundThemeBrush}" Height="{StaticResource SliderOutsideTickBarThemeHeight}" Margin="0,2,0,0" Grid.Row="2" Visibility="Collapsed" VerticalAlignment="Top"/>
                            <Rectangle x:Name="HorizontalBorder" Grid.ColumnSpan="3" Grid.Row="1" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="{TemplateBinding BorderThickness}"/>
                            <Thumb x:Name="HorizontalThumb"  
                                   Grid.Column="1" 
                                   DataContext="{TemplateBinding Value}"
                                   Width="40"
                                   Height="30" 
                                   Grid.Row="1" >
                                <Thumb.Background>
                                    <ImageBrush ImageSource="/Assets/bus_thumb.png" />
                                </Thumb.Background>
                            </Thumb>
                            <Rectangle x:Name="FocusVisualWhiteHorizontal" Grid.ColumnSpan="3" IsHitTestVisible="False" Opacity="0" Grid.RowSpan="3" StrokeDashOffset="1.5" StrokeEndLineCap="Square" Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}" StrokeDashArray="1,1"/>
                            <Rectangle x:Name="FocusVisualBlackHorizontal" Grid.ColumnSpan="3" IsHitTestVisible="False" Opacity="0" Grid.RowSpan="3" StrokeDashOffset="0.5" StrokeEndLineCap="Square" Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}" StrokeDashArray="1,1"/>
                        </Grid>
                        <Grid x:Name="VerticalTemplate" Background="Transparent" Visibility="Collapsed">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="17"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="17"/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="*"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <Rectangle x:Name="VerticalTrackRect" Grid.Column="1" Fill="{TemplateBinding Background}" Grid.RowSpan="3"/>
                            <Rectangle x:Name="VerticalDecreaseRect" Grid.Column="1" Fill="{TemplateBinding Foreground}" Grid.Row="2"/>
                            <TickBar x:Name="LeftTickBar" Fill="{StaticResource SliderTickmarkOutsideBackgroundThemeBrush}" HorizontalAlignment="Right" Margin="0,0,2,0" Grid.RowSpan="3" Visibility="Collapsed" Width="{StaticResource SliderOutsideTickBarThemeHeight}"/>
                            <TickBar x:Name="VerticalInlineTickBar" Grid.Column="1" Fill="{StaticResource SliderTickMarkInlineBackgroundThemeBrush}" Grid.RowSpan="3" Visibility="Collapsed" Width="{StaticResource SliderTrackThemeHeight}"/>
                            <TickBar x:Name="RightTickBar" Grid.Column="2" Fill="{StaticResource SliderTickmarkOutsideBackgroundThemeBrush}" HorizontalAlignment="Left" Margin="2,0,0,0" Grid.RowSpan="3" Visibility="Collapsed" Width="{StaticResource SliderOutsideTickBarThemeHeight}"/>
                            <Rectangle x:Name="VerticalBorder" Grid.Column="1" Grid.RowSpan="3" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="{TemplateBinding BorderThickness}"/>
                            <Thumb x:Name="VerticalThumb" 
                                Background="{StaticResource SliderThumbBackgroundThemeBrush}" 
                                Grid.Column="1" DataContext="{TemplateBinding Value}" Height="{StaticResource SliderTrackThemeHeight}" Grid.Row="1" 
                                Width="{StaticResource SliderTrackThemeHeight}"/>
                            <Rectangle x:Name="FocusVisualWhiteVertical" Grid.ColumnSpan="3" IsHitTestVisible="False" Opacity="0" Grid.RowSpan="3" StrokeDashOffset="1.5" StrokeEndLineCap="Square" Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}" StrokeDashArray="1,1"/>
                            <Rectangle x:Name="FocusVisualBlackVertical" Grid.ColumnSpan="3" IsHitTestVisible="False" Opacity="0" Grid.RowSpan="3" StrokeDashOffset="0.5" StrokeEndLineCap="Square" Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}" StrokeDashArray="1,1"/>
                        </Grid>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <Slider x:Name="busSlider" Width="220" Height="50" Minimum="0" Maximum="100" Value="0" Orientation="Horizontal" IsEnabled="True"  Style="{StaticResource BusRouteSliderStyle}" />

    <TextBlock x:Name="lblSliderStopInfo" Grid.Row="1" Foreground="White" FontSize="12" Text ="{Binding ElementName=slider,  Path=Value}" />

</Grid>

Upvotes: 5

Views: 3247

Answers (2)

Carlos P
Carlos P

Reputation: 3989

As I suspected, I needed to change the style of the Thumb control, but it wasn't easy to extract it within VIsual Studio, since it was already contained within a ControlTemplate.

The solution was as follows:

  • Create a brand new Thumb control on a blank XAML page, giving it a height/width so it's visible on the designer canvas.
  • Right-click it, choose 'Edit Template' -> 'Edit a Copy'
  • This creates the template within the XAML which can then be copied/pasted elsewhere as required.

The default Thumb style is pasted below for anyone who needs it. Just remove the PointerOver and Pressed states to achieve the behaviour I wanted.

  <Style x:Key="ThumbStyle1" TargetType="Thumb">
        <Setter Property="Background" Value="{StaticResource ThumbBackgroundThemeBrush}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="IsTabStop" Value="False"/>
        <Setter Property="BorderBrush" Value="{StaticResource ThumbBorderThemeBrush}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Thumb">
                    <Grid>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="PointerOver">
                                    <Storyboard>
                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundPointerOver"/>
                                        <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Background"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Pressed">
                                    <Storyboard>
                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundPressed"/>
                                        <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Background"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Disabled"/>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="FocusStates">
                                <VisualState x:Name="Unfocused"/>
                                <VisualState x:Name="Focused"/>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Border x:Name="Background" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"/>
                        <Border x:Name="BackgroundPointerOver" BorderBrush="{StaticResource ThumbPointerOverBorderThemeBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{StaticResource ThumbPointerOverBackgroundThemeBrush}" Opacity="0"/>
                        <Border x:Name="BackgroundPressed" BorderBrush="{StaticResource ThumbPressedBorderThemeBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{StaticResource ThumbPressedBackgroundThemeBrush}" Opacity="0"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Upvotes: 3

Filip Skakun
Filip Skakun

Reputation: 31724

You probably need to also change the style/template of the Thumb control.

Upvotes: 3

Related Questions