none
sliders in xaml

    Question

  • hi all,

    i am new to wpf and was hoping someone could point me in the right direction

     

    i understand that a generic slider is built in but what if i want to modify it?  i know that you need to adjust the style for it.

    1) where is the style code for a slider?

    2) how do i know which attributes i need to change?  for example, i want to change the 'slider' (default is a rectangle) to a circle? 

    so its like  -------O-------  instead of  --------[]------- what do i need to modify for the slider?

     

    thanks alot for the help :)
    Wednesday, February 04, 2009 6:35 AM

Answers

  • EDIT: I see now that the simpleslider was an ellipse to start with, and I changed it to a rectangle, you wanted it the other way around, but I hope you get the point

    I'm sure there are many different approaches, here is one:
    To change parts of the slider you need to change the controltemplate (the visuals of the slider).
     I usually start from the Simple xxxx -parts from Blend instead of the standard, if you add a simple Slider in Blend, and look at the resources, Blen has added a resourcedictionary SimpleStyles.XAML (there are a lot of tools for looking at templates, but I find SimpleStyles to be easier to read). The slider you added will be styled as:
    <Slider  Style="{DynamicResource SimpleSlider}"/>

    So by looking for the SimpleSlider resource: (you cant use it directly, because its referencing some otheer simple resources)
    <!--Simple Simple Slider  
        Similiar to ScrollBar this template uses Track to layout the draggable Thumb which has an up and down repeat button  
        It uses Simple SliderThumb and SimpleScrollRepeatButtonStyle for the page up and down repeat buttons --> 
        <Style x:Key="SimpleSlider" TargetType="{x:Type Slider}">  
            <Setter Property="Background" Value="{DynamicResource LightBrush}"/>  
            <Setter Property="BorderBrush" Value="{DynamicResource NormalBorderBrush}"/>  
            <Setter Property="Template">  
                <Setter.Value> 
                    <ControlTemplate TargetType="{x:Type Slider}">  
                        <Grid x:Name="GridRoot">  
                            <Grid.RowDefinitions> 
                                <RowDefinition Height="Auto"/>  
                                <RowDefinition Height="Auto" MinHeight="{TemplateBinding MinHeight}"/>  
                                <RowDefinition Height="Auto"/>  
                            </Grid.RowDefinitions> 
                              
                            <!-- TickBar shows the ticks for Slider --> 
                            <TickBar Visibility="Collapsed" x:Name="TopTick" Height="4" SnapsToDevicePixels="True" Placement="Top" Fill="{DynamicResource GlyphBrush}"/>  
                            <Border Grid.Row="1" Margin="0" x:Name="Border" Height="4" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2"/>  
                              
                            <!-- The Track lays out the repeat buttons and thumb --> 
                            <Track Grid.Row="1" x:Name="PART_Track">  
                                <Track.Thumb> 
                                    <Thumb Style="{DynamicResource SimpleSliderThumb}"/>  
                                </Track.Thumb> 
                                <Track.IncreaseRepeatButton> 
                                    <RepeatButton Style="{DynamicResource SimpleScrollRepeatButtonStyle}" Command="Slider.IncreaseLarge"/>  
                                </Track.IncreaseRepeatButton> 
                                <Track.DecreaseRepeatButton> 
                                    <RepeatButton Style="{DynamicResource SimpleScrollRepeatButtonStyle}" Command="Slider.DecreaseLarge"/>  
                                </Track.DecreaseRepeatButton> 
                            </Track> 
                              
                            <TickBar Visibility="Collapsed" Grid.Row="2" x:Name="BottomTick" Height="4" SnapsToDevicePixels="True" Placement="Bottom" Fill="{TemplateBinding Foreground}"/>  
                        </Grid> 
                        <ControlTemplate.Triggers> 
                            <Trigger Property="TickPlacement" Value="TopLeft">  
                                <Setter Property="Visibility" Value="Visible" TargetName="TopTick"/>  
                            </Trigger> 
                            <Trigger Property="TickPlacement" Value="BottomRight">  
                                <Setter Property="Visibility" Value="Visible" TargetName="BottomTick"/>  
                            </Trigger> 
                            <Trigger Property="TickPlacement" Value="Both">  
                                <Setter Property="Visibility" Value="Visible" TargetName="TopTick"/>  
                                <Setter Property="Visibility" Value="Visible" TargetName="BottomTick"/>  
                            </Trigger> 
                            <Trigger Property="IsEnabled" Value="false">  
                                <Setter Property="Background" Value="{DynamicResource DisabledBackgroundBrush}" TargetName="Border"/>  
                                <Setter Property="BorderBrush" Value="{DynamicResource DisabledBorderBrush}" TargetName="Border"/>  
                            </Trigger> 
                              
                            <!-- Use a rotation to create a Vertical Slider form the default Horizontal --> 
                            <Trigger Property="Orientation" Value="Vertical">  
                                <Setter Property="LayoutTransform" TargetName="GridRoot">  
                                    <Setter.Value> 
                                        <RotateTransform Angle="-90"/>  
                                    </Setter.Value> 
                                </Setter> 
                                <!-- Track rotates itself based on orientation so need to force it back --> 
                                <Setter TargetName="PART_Track" Property="Orientation" Value="Horizontal"/>  
                            </Trigger> 
                              
                        </ControlTemplate.Triggers> 
                    </ControlTemplate> 
                </Setter.Value> 
            </Setter> 
        </Style> 
    We see that it uses SimpleSliderThumb ,and it looks like:
    <!--Simple Simple SliderThumb - The Thumb is the draggable part of a Slider--> 
        <Style x:Key="SimpleSliderThumb" d:IsControlPart="True" TargetType="{x:Type Thumb}">  
            <Setter Property="SnapsToDevicePixels" Value="true"/>  
            <Setter Property="Height" Value="14"/>  
            <Setter Property="Width" Value="14"/>  
            <Setter Property="Template">  
                <Setter.Value> 
                    <ControlTemplate TargetType="{x:Type Thumb}">  
                        <Grid> 
                            <Ellipse x:Name="Ellipse" Fill="{DynamicResource NormalBrush}" Stroke="{DynamicResource NormalBorderBrush}" StrokeThickness="1"/>  
                        </Grid> 
                        <ControlTemplate.Triggers> 
                            <Trigger Property="IsMouseOver" Value="True">  
                                <Setter Property="Fill" Value="{DynamicResource MouseOverBrush}" TargetName="Ellipse"/>  
                            </Trigger> 
                            <Trigger Property="IsEnabled" Value="false">  
                                <Setter Property="Fill" Value="{DynamicResource DisabledBackgroundBrush}" TargetName="Ellipse"/>  
                            </Trigger> 
                        </ControlTemplate.Triggers> 
                    </ControlTemplate> 
                </Setter.Value> 
            </Setter> 
        </Style> 
    We can see that its drawn as an ellipse , change that to rectangle and it will work as you described. A lot of code to do a rectangle maybe, but its really flexible and easy to read.
    <Rectangle x:Name="Ellipse" Fill="{DynamicResource NormalBrush}" Stroke="{DynamicResource NormalBorderBrush}" StrokeThickness="1"/> 
    (I would have changed the name as well)
    Hope it helps.
    /Henke
    • Marked as answer by Hua Chen Tuesday, February 10, 2009 10:09 AM
    Wednesday, February 04, 2009 6:57 AM
  • Using Templates to Customize WPF Controls
    http://msdn.microsoft.com/en-us/magazine/cc163497.aspx

    ScrollBar ControlTemplate Example
    http://msdn.microsoft.com/en-us/library/ms742173.aspx
    • Marked as answer by Hua Chen Tuesday, February 10, 2009 10:09 AM
    Wednesday, February 04, 2009 7:00 AM

All replies

  • EDIT: I see now that the simpleslider was an ellipse to start with, and I changed it to a rectangle, you wanted it the other way around, but I hope you get the point

    I'm sure there are many different approaches, here is one:
    To change parts of the slider you need to change the controltemplate (the visuals of the slider).
     I usually start from the Simple xxxx -parts from Blend instead of the standard, if you add a simple Slider in Blend, and look at the resources, Blen has added a resourcedictionary SimpleStyles.XAML (there are a lot of tools for looking at templates, but I find SimpleStyles to be easier to read). The slider you added will be styled as:
    <Slider  Style="{DynamicResource SimpleSlider}"/>

    So by looking for the SimpleSlider resource: (you cant use it directly, because its referencing some otheer simple resources)
    <!--Simple Simple Slider  
        Similiar to ScrollBar this template uses Track to layout the draggable Thumb which has an up and down repeat button  
        It uses Simple SliderThumb and SimpleScrollRepeatButtonStyle for the page up and down repeat buttons --> 
        <Style x:Key="SimpleSlider" TargetType="{x:Type Slider}">  
            <Setter Property="Background" Value="{DynamicResource LightBrush}"/>  
            <Setter Property="BorderBrush" Value="{DynamicResource NormalBorderBrush}"/>  
            <Setter Property="Template">  
                <Setter.Value> 
                    <ControlTemplate TargetType="{x:Type Slider}">  
                        <Grid x:Name="GridRoot">  
                            <Grid.RowDefinitions> 
                                <RowDefinition Height="Auto"/>  
                                <RowDefinition Height="Auto" MinHeight="{TemplateBinding MinHeight}"/>  
                                <RowDefinition Height="Auto"/>  
                            </Grid.RowDefinitions> 
                              
                            <!-- TickBar shows the ticks for Slider --> 
                            <TickBar Visibility="Collapsed" x:Name="TopTick" Height="4" SnapsToDevicePixels="True" Placement="Top" Fill="{DynamicResource GlyphBrush}"/>  
                            <Border Grid.Row="1" Margin="0" x:Name="Border" Height="4" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2"/>  
                              
                            <!-- The Track lays out the repeat buttons and thumb --> 
                            <Track Grid.Row="1" x:Name="PART_Track">  
                                <Track.Thumb> 
                                    <Thumb Style="{DynamicResource SimpleSliderThumb}"/>  
                                </Track.Thumb> 
                                <Track.IncreaseRepeatButton> 
                                    <RepeatButton Style="{DynamicResource SimpleScrollRepeatButtonStyle}" Command="Slider.IncreaseLarge"/>  
                                </Track.IncreaseRepeatButton> 
                                <Track.DecreaseRepeatButton> 
                                    <RepeatButton Style="{DynamicResource SimpleScrollRepeatButtonStyle}" Command="Slider.DecreaseLarge"/>  
                                </Track.DecreaseRepeatButton> 
                            </Track> 
                              
                            <TickBar Visibility="Collapsed" Grid.Row="2" x:Name="BottomTick" Height="4" SnapsToDevicePixels="True" Placement="Bottom" Fill="{TemplateBinding Foreground}"/>  
                        </Grid> 
                        <ControlTemplate.Triggers> 
                            <Trigger Property="TickPlacement" Value="TopLeft">  
                                <Setter Property="Visibility" Value="Visible" TargetName="TopTick"/>  
                            </Trigger> 
                            <Trigger Property="TickPlacement" Value="BottomRight">  
                                <Setter Property="Visibility" Value="Visible" TargetName="BottomTick"/>  
                            </Trigger> 
                            <Trigger Property="TickPlacement" Value="Both">  
                                <Setter Property="Visibility" Value="Visible" TargetName="TopTick"/>  
                                <Setter Property="Visibility" Value="Visible" TargetName="BottomTick"/>  
                            </Trigger> 
                            <Trigger Property="IsEnabled" Value="false">  
                                <Setter Property="Background" Value="{DynamicResource DisabledBackgroundBrush}" TargetName="Border"/>  
                                <Setter Property="BorderBrush" Value="{DynamicResource DisabledBorderBrush}" TargetName="Border"/>  
                            </Trigger> 
                              
                            <!-- Use a rotation to create a Vertical Slider form the default Horizontal --> 
                            <Trigger Property="Orientation" Value="Vertical">  
                                <Setter Property="LayoutTransform" TargetName="GridRoot">  
                                    <Setter.Value> 
                                        <RotateTransform Angle="-90"/>  
                                    </Setter.Value> 
                                </Setter> 
                                <!-- Track rotates itself based on orientation so need to force it back --> 
                                <Setter TargetName="PART_Track" Property="Orientation" Value="Horizontal"/>  
                            </Trigger> 
                              
                        </ControlTemplate.Triggers> 
                    </ControlTemplate> 
                </Setter.Value> 
            </Setter> 
        </Style> 
    We see that it uses SimpleSliderThumb ,and it looks like:
    <!--Simple Simple SliderThumb - The Thumb is the draggable part of a Slider--> 
        <Style x:Key="SimpleSliderThumb" d:IsControlPart="True" TargetType="{x:Type Thumb}">  
            <Setter Property="SnapsToDevicePixels" Value="true"/>  
            <Setter Property="Height" Value="14"/>  
            <Setter Property="Width" Value="14"/>  
            <Setter Property="Template">  
                <Setter.Value> 
                    <ControlTemplate TargetType="{x:Type Thumb}">  
                        <Grid> 
                            <Ellipse x:Name="Ellipse" Fill="{DynamicResource NormalBrush}" Stroke="{DynamicResource NormalBorderBrush}" StrokeThickness="1"/>  
                        </Grid> 
                        <ControlTemplate.Triggers> 
                            <Trigger Property="IsMouseOver" Value="True">  
                                <Setter Property="Fill" Value="{DynamicResource MouseOverBrush}" TargetName="Ellipse"/>  
                            </Trigger> 
                            <Trigger Property="IsEnabled" Value="false">  
                                <Setter Property="Fill" Value="{DynamicResource DisabledBackgroundBrush}" TargetName="Ellipse"/>  
                            </Trigger> 
                        </ControlTemplate.Triggers> 
                    </ControlTemplate> 
                </Setter.Value> 
            </Setter> 
        </Style> 
    We can see that its drawn as an ellipse , change that to rectangle and it will work as you described. A lot of code to do a rectangle maybe, but its really flexible and easy to read.
    <Rectangle x:Name="Ellipse" Fill="{DynamicResource NormalBrush}" Stroke="{DynamicResource NormalBorderBrush}" StrokeThickness="1"/> 
    (I would have changed the name as well)
    Hope it helps.
    /Henke
    • Marked as answer by Hua Chen Tuesday, February 10, 2009 10:09 AM
    Wednesday, February 04, 2009 6:57 AM
  • Using Templates to Customize WPF Controls
    http://msdn.microsoft.com/en-us/magazine/cc163497.aspx

    ScrollBar ControlTemplate Example
    http://msdn.microsoft.com/en-us/library/ms742173.aspx
    • Marked as answer by Hua Chen Tuesday, February 10, 2009 10:09 AM
    Wednesday, February 04, 2009 7:00 AM