Mitch
Mitch

Reputation: 2551

WPF/Silverlight Slider control display tick numbers

I'm using a WPF Slider control (I'm guessing the Silverlight version is similar) that's set to horizontal and has a Min Value of 0 and a Max Value of 5.

I'd like to display the values 0 - 5 below the tick marks to make it a bit more obvious which value the thumb is currently pointing to.

Is this possible and has anybody managed to achieve this?

Upvotes: 6

Views: 10762

Answers (2)

nikhil
nikhil

Reputation: 1736

Adding a bit more detail to the above answer. This is how we did it, firstly edit the default Slider Control and generate the xaml in Blend.

Here is the entire style and yes instead of CustomTickBar replace the NumberedTickBar and use the Template for your Slider as Horizontal Slider as provided in the style.

<SolidColorBrush
            x:Key="SliderThumb.Static.Foreground"
            Color="#FFE5E5E5" />
        <SolidColorBrush
            x:Key="SliderThumb.MouseOver.Background"
            Color="#FFDCECFC" />
        <SolidColorBrush
            x:Key="SliderThumb.MouseOver.Border"
            Color="#FF7Eb4EA" />
        <SolidColorBrush
            x:Key="SliderThumb.Pressed.Background"
            Color="#FFDAECFC" />
        <SolidColorBrush
            x:Key="SliderThumb.Pressed.Border"
            Color="#FF569DE5" />
        <SolidColorBrush
            x:Key="SliderThumb.Disabled.Background"
            Color="#FFF0F0F0" />
        <SolidColorBrush
            x:Key="SliderThumb.Disabled.Border"
            Color="#FFD9D9D9" />
        <SolidColorBrush
            x:Key="SliderThumb.Static.Background"
            Color="#FFF0F0F0" />
        <SolidColorBrush
            x:Key="SliderThumb.Static.Border"
            Color="#FFACACAC" />
        <SolidColorBrush
            x:Key="SliderThumb.Track.Border"
            Color="#FFD6D6D6" />
        <SolidColorBrush
            x:Key="SliderThumb.Track.Background"
            Color="Red" />
        <Style
            x:Key="RepeatButtonTransparent"
            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
                            Fill="{TemplateBinding Background}"
                            Height="{TemplateBinding Height}"
                            Width="{TemplateBinding Width}" />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style
            x:Key="SliderThumbStyle"
            TargetType="{x:Type Thumb}">
            <Setter
                Property="SnapsToDevicePixels"
                Value="true" />
            <Setter
                Property="OverridesDefaultStyle"
                Value="true" />
            <Setter
                Property="Height"
                Value="18" />
            <Setter
                Property="Width"
                Value="18" />
            <Setter
                Property="Template">
                <Setter.Value>
                    <ControlTemplate
                        TargetType="{x:Type Thumb}">
                        <Ellipse
                            Name="Ellipse"
                            Fill="Orange"
                            Stroke="#404040"
                            StrokeThickness="1" />
                        <ControlTemplate.Triggers>
                            <Trigger
                                Property="IsMouseOver"
                                Value="True">
                                <Setter
                                    TargetName="Ellipse"
                                    Property="Fill"
                                    Value="#FFC3C0FF" />

                            </Trigger>
                            <Trigger
                                Property="IsEnabled"
                                Value="false">
                                <Setter
                                    TargetName="Ellipse"
                                    Property="Fill"
                                    Value="#EEEEEE" />

                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <ControlTemplate
            x:Key="SliderThumbHorizontalDefault"
            TargetType="{x:Type Thumb}">
            <Grid
                HorizontalAlignment="Center"
                UseLayoutRounding="True"
                VerticalAlignment="Center">
                <Path
                    x:Name="grip"
                    Data="M 0,0 C0,0 11,0 11,0 11,0 11,18 11,18 11,18 0,18 0,18 0,18 0,0 0,0 z"
                    Fill="{StaticResource SliderThumb.Static.Background}"
                    Stretch="Fill"
                    SnapsToDevicePixels="True"
                    Stroke="{StaticResource SliderThumb.Static.Border}"
                    StrokeThickness="1"
                    UseLayoutRounding="True"
                    VerticalAlignment="Center" />
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger
                    Property="IsMouseOver"
                    Value="true">
                    <Setter
                        Property="Fill"
                        TargetName="grip"
                        Value="{StaticResource SliderThumb.MouseOver.Background}" />
                    <Setter
                        Property="Stroke"
                        TargetName="grip"
                        Value="{StaticResource SliderThumb.MouseOver.Border}" />
                </Trigger>
                <Trigger
                    Property="IsDragging"
                    Value="true">
                    <Setter
                        Property="Fill"
                        TargetName="grip"
                        Value="{StaticResource SliderThumb.Pressed.Background}" />
                    <Setter
                        Property="Stroke"
                        TargetName="grip"
                        Value="{StaticResource SliderThumb.Pressed.Border}" />
                </Trigger>
                <Trigger
                    Property="IsEnabled"
                    Value="false">
                    <Setter
                        Property="Fill"
                        TargetName="grip"
                        Value="{StaticResource SliderThumb.Disabled.Background}" />
                    <Setter
                        Property="Stroke"
                        TargetName="grip"
                        Value="{StaticResource SliderThumb.Disabled.Border}" />
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
        <ControlTemplate
            x:Key="HorizontalSlider"
            TargetType="{x:Type Slider}">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition
                        Height="Auto" />
                    <RowDefinition
                        Height="Auto"
                        MinHeight="{TemplateBinding Slider.MinHeight}" />
                    <RowDefinition
                        Height="Auto" />
                </Grid.RowDefinitions>
                <Custom:CustomTickBar
                    Margin="5,0,10,0"
                    x:Name="TopTick"
                    SnapsToDevicePixels="True"
                    Placement="Top"
                    Fill="Green"
                    Height="5" />
                <Border
                    Name="TrackBackground"
                    Margin="0"
                    CornerRadius="2"
                    Height="4"
                    Grid.Row="1"
                    Background="{StaticResource SliderThumb.Track.Background}"
                    BorderBrush="{StaticResource SliderThumb.Track.Border}"
                    BorderThickness="1" />
                <Track
                    Grid.Row="1"
                    Name="PART_Track">
                    <Track.DecreaseRepeatButton>
                        <RepeatButton
                            Style="{StaticResource RepeatButtonTransparent}"
                            Command="Slider.DecreaseLarge" />
                    </Track.DecreaseRepeatButton>
                    <Track.Thumb>
                        <Thumb
                            Style="{StaticResource SliderThumbStyle}" />
                        <!--<Thumb
                            Style="{StaticResource SliderThumbHorizontalDefault}" />-->
                    </Track.Thumb>
                    <Track.IncreaseRepeatButton>
                        <RepeatButton
                            Style="{StaticResource RepeatButtonTransparent}"
                            Command="Slider.IncreaseLarge" />
                    </Track.IncreaseRepeatButton>
                </Track>
                <TickBar
                    Name="BottomTick"
                    SnapsToDevicePixels="True"
                    Grid.Row="2"
                    Fill="Black"
                    Placement="Bottom"
                    Height="10"
                    Visibility="Collapsed" />
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger
                    Property="TickPlacement"
                    Value="TopLeft">
                    <Setter
                        TargetName="TopTick"
                        Property="Visibility"
                        Value="Visible" />
                </Trigger>
                <Trigger
                    Property="TickPlacement"
                    Value="BottomRight">
                    <Setter
                        TargetName="BottomTick"
                        Property="Visibility"
                        Value="Visible" />
                </Trigger>
                <Trigger
                    Property="TickPlacement"
                    Value="Both">
                    <Setter
                        TargetName="TopTick"
                        Property="Visibility"
                        Value="Visible" />
                    <Setter
                        TargetName="BottomTick"
                        Property="Visibility"
                        Value="Visible" />
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>

Upvotes: 0

Liz
Liz

Reputation: 8958

I believe the best way to do this is to create a custom TickBar control and override the Rendering of the ticks. Here is one way:

public class NumberedTickBar : TickBar
  {
    protected override void OnRender(DrawingContext dc)
    {

      Size size = new Size(base.ActualWidth,base.ActualHeight);
      int tickCount = (int)((this.Maximum - this.Minimum) / this.TickFrequency) + 1;
      if((this.Maximum - this.Minimum) % this.TickFrequency == 0)
        tickCount -= 1;
      Double tickFrequencySize;
      // Calculate tick's setting
      tickFrequencySize = (size.Width * this.TickFrequency / (this.Maximum - this.Minimum));
      string text = "";
      FormattedText formattedText = null;
      double num = this.Maximum - this.Minimum;
      int i = 0;
      // Draw each tick text
      for(i = 0;i <= tickCount;i++)
      {
        text = Convert.ToString(Convert.ToInt32(this.Minimum + this.TickFrequency * i),10);

        formattedText = new FormattedText(text,CultureInfo.GetCultureInfo("en-us"),FlowDirection.LeftToRight,new Typeface("Verdana"),8,Brushes.Black);
        dc.DrawText(formattedText,new Point((tickFrequencySize * i),30));

      }
    }
  }

Then you'll have to create a custom style for your slider that uses your new Tickbar instead of the default tickbar.

If you are not sure how to create a style for a slider you can start with the windows example here. It's a very sophisticated one.

Then the only thing left to do is to replace the Top Tickbar with your new custom one. Basically change:

<TickBar Name="TopTick" SnapsToDevicePixels="True" Placement="Top" Fill="{StaticResource GlyphBrush}" Height="4" Visibility="Collapsed" />

to this:

<local:NumberedTickBar Name="TopTick" Margin="5,0,10,0" SnapsToDevicePixels="True" Grid.Row="0" Fill="{TemplateBinding Foreground}" Placement="Top" Height="4" Visibility="Collapsed"/>

The margin is important because that will ensure that your text is in the right place.

Your slider will be on the top with ticks just below it. A row of text will be displayed below the ticks.

Upvotes: 11

Related Questions