版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SANYUNI/article/details/51576176
扩展了WPF的Slider 支持给三张图:背景、前景、滑块,支持设置滑块大小、设置高亮部分的宽度或高度。具体代码如下:
Xaml: 里面用到了MahApps.Metro这个库
<Slider x:Class="ContentItem.ExSlider"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ContentItem"
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Slider.Resources>
<!--HorizontalSliderThumb-->
<Style x:Key="HorizontalSliderThumb" TargetType="Thumb">
<Setter Property="Background" Value="{DynamicResource GrayBrush10}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<Border Background="Transparent"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="2.5"
Opacity=".55"
BorderBrush="{DynamicResource ControlBackgroundBrush}" />
<Rectangle x:Name="DisabledVisualElement"
Fill="{TemplateBinding Background}"
IsHitTestVisible="false"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--HorizontalTrackLargeDecrease-->
<Style x:Key="HorizontalTrackLargeDecrease" TargetType="{x:Type RepeatButton}">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="IsTabStop" Value="false" />
<Setter Property="Focusable" Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}" >
<Border x:Name="Root" Height="{Binding RelativeSource={RelativeSource AncestorType=local:ExSlider},Path=TrackSize}"
Width="{TemplateBinding Width}">
<Rectangle IsHitTestVisible="True" Height="{Binding RelativeSource={RelativeSource AncestorType=local:ExSlider},Path=TrackSize}" Fill="{TemplateBinding Background}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="HorizontalTrackValue" TargetType="{x:Type RepeatButton}">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="IsTabStop" Value="false" />
<Setter Property="Focusable" Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border x:Name="Root" BorderThickness="0" Height="{Binding RelativeSource={RelativeSource AncestorType=local:ExSlider},Path=TrackSize}"
Width="{TemplateBinding Width}">
<Image Stretch="Fill"
Width="{Binding RelativeSource={RelativeSource AncestorType=local:ExSlider},Path=Width}"
Height="{Binding RelativeSource={RelativeSource AncestorType=local:ExSlider},Path=TrackSize}"
Source="{Binding RelativeSource={RelativeSource AncestorType=local:ExSlider},Path=DecreaseImage}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="HorizontalSliderTemplate" TargetType="Slider">
<Grid x:Name="Root">
<Grid x:Name="HorizontalTemplate" Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" MinHeight="{TemplateBinding Slider.MinHeight}" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TickBar x:Name="TopTick"
Visibility="Collapsed"
Fill="{TemplateBinding Foreground}"
Placement="Top"
Height="4"
Grid.Row="0" />
<TickBar x:Name="BottomTick"
Visibility="Collapsed"
Fill="{TemplateBinding Foreground}"
Placement="Bottom"
Height="4"
Grid.Row="2" />
<Track x:Name="PART_Track" Grid.Row="1" Height="{TemplateBinding Height}">
<Track.DecreaseRepeatButton>
<RepeatButton x:Name="Dec" Command="{x:Static Slider.DecreaseLarge}"
Style="{StaticResource HorizontalTrackValue}" />
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Command="{x:Static Slider.IncreaseLarge}"
Style="{StaticResource HorizontalTrackLargeDecrease}" />
</Track.IncreaseRepeatButton>
<Track.Thumb>
<mah:MetroThumb x:Name="HorizontalThumb"
BorderThickness="0"
Background="{Binding RelativeSource={RelativeSource AncestorType=local:ExSlider},Path=ThumbImage}"
Height="{Binding RelativeSource={RelativeSource AncestorType=local:ExSlider},Path=ThumbHeight}"
IsTabStop="True"
Width="{Binding RelativeSource={RelativeSource AncestorType=local:ExSlider},Path=ThumbWidth}"
Style="{StaticResource HorizontalSliderThumb}" />
</Track.Thumb>
</Track>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Dec" Property="Visibility" Value="Hidden"/>
<Setter TargetName="HorizontalThumb" Property="Opacity" Value="0.5"/>
</Trigger>
<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>
<!--VerticalSliderThumb-->
<Style x:Key="VerticalSliderThumb" TargetType="Thumb">
<Setter Property="Background" Value="{DynamicResource GrayBrush10}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<Border Background="Transparent"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="2.5"
Opacity=".55"
BorderBrush="{DynamicResource ControlBackgroundBrush}" />
<Rectangle x:Name="DisabledVisualElement"
Fill="{TemplateBinding Background}"
IsHitTestVisible="false"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="VerticalTrackLargeDecrease" TargetType="{x:Type RepeatButton}">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="IsTabStop" Value="false" />
<Setter Property="Focusable" Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}" >
<Border x:Name="Root" Width="{Binding RelativeSource={RelativeSource AncestorType=local:ExSlider},Path=TrackSize}"
Height="{TemplateBinding Height}">
<Rectangle IsHitTestVisible="True" Width="{Binding RelativeSource={RelativeSource AncestorType=local:ExSlider},Path=TrackSize}" Fill="{TemplateBinding Background}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="VerticalTrackValue" TargetType="{x:Type RepeatButton}">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="IsTabStop" Value="false" />
<Setter Property="Focusable" Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border x:Name="Root" BorderThickness="0" Width="{Binding RelativeSource={RelativeSource AncestorType=local:ExSlider},Path=TrackSize}"
Height="{TemplateBinding Height}" RenderTransformOrigin="0.5,0.5">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="180"/>
<TranslateTransform X="0" Y="0.5"/>
</TransformGroup>
</Border.RenderTransform>
<Image
Stretch="Fill"
Width="{Binding RelativeSource={RelativeSource AncestorType=local:ExSlider},Path=TrackSize}"
Height="{Binding RelativeSource={RelativeSource AncestorType=local:ExSlider},Path=Height}"
Source="{Binding RelativeSource={RelativeSource AncestorType=local:ExSlider},Path=DecreaseImage}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="VerticalSliderTemplate" TargetType="Slider">
<Grid x:Name="Root">
<Grid x:Name="HorizontalTemplate"
Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" MinWidth="{TemplateBinding Slider.MinWidth}" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TickBar x:Name="TopTick" Visibility="Collapsed" Fill="{TemplateBinding Foreground}" Placement="Left"
Width="4"
Grid.Column="0" />
<TickBar x:Name="BottomTick"
Visibility="Collapsed"
Fill="{TemplateBinding Foreground}"
Placement="Right"
Width="4"
Grid.Column="2" />
<Track x:Name="PART_Track" Grid.Column="1" Width="{TemplateBinding Width}">
<Track.DecreaseRepeatButton>
<RepeatButton x:Name="Dec" Command="{x:Static Slider.DecreaseLarge}"
Style="{StaticResource VerticalTrackValue}" />
<!--Style="{StaticResource VerticalTrackValue}" />-->
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Command="{x:Static Slider.IncreaseLarge}"
Style="{StaticResource VerticalTrackLargeDecrease}" />
<!--Style="{StaticResource VerticalTrackLargeDecrease}" />-->
</Track.IncreaseRepeatButton>
<Track.Thumb>
<mah:MetroThumb x:Name="VerticalThumb"
BorderThickness="0"
Background="{Binding RelativeSource={RelativeSource AncestorType=local:ExSlider},Path=ThumbImage}"
Height="{Binding RelativeSource={RelativeSource AncestorType=local:ExSlider},Path=ThumbHeight}"
IsTabStop="True"
Width="{Binding RelativeSource={RelativeSource AncestorType=local:ExSlider},Path=ThumbWidth}"
Style="{StaticResource VerticalSliderThumb}" />
</Track.Thumb>
</Track>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Dec" Property="Visibility" Value="Hidden"/>
<Setter TargetName="VerticalThumb" Property="Opacity" Value="0.5"/>
</Trigger>
<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>
<!--Slider Style-->
<Style TargetType="local:ExSlider">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Maximum" Value="100" />
<Setter Property="Minimum" Value="0" />
<Setter Property="Value" Value="0" />
<Setter Property="IsMoveToPointEnabled" Value="True"/>
<Setter Property="BorderBrush" Value="{DynamicResource ControlBorderBrush}" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Template" Value="{DynamicResource HorizontalSliderTemplate}" />
<Setter Property="Foreground" Value="{DynamicResource TextBrush}" />
<Style.Triggers>
<Trigger Property="Orientation" Value="Vertical">
<Setter Property="Template" Value="{DynamicResource VerticalSliderTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
</Slider.Resources>
</Slider>
后台代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace ContentItem
{
/// <summary>
/// ExSlider.xaml 的交互逻辑
/// </summary>
public partial class ExSlider : Slider
{
public ExSlider()
{
InitializeComponent();
}
public int TrackSize
{
get { return (int)GetValue(TrackSizeProperty); }
set { SetValue(TrackSizeProperty, value); }
}
// Using a DependencyProperty as the backing store for TraceSize. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TrackSizeProperty =
DependencyProperty.Register("TrackSize", typeof(int), typeof(ExSlider), new PropertyMetadata(5));
public int ThumbWidth
{
get { return (int)GetValue(ThumbWidthProperty); }
set { SetValue(ThumbWidthProperty, value); }
}
// Using a DependencyProperty as the backing store for ThumbWidth. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ThumbWidthProperty =
DependencyProperty.Register("ThumbWidth", typeof(int), typeof(ExSlider), new PropertyMetadata(10));
public int ThumbHeight
{
get { return (int)GetValue(ThumbHeightProperty); }
set { SetValue(ThumbHeightProperty, value); }
}
// Using a DependencyProperty as the backing store for ThumbHeight. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ThumbHeightProperty =
DependencyProperty.Register("ThumbHeight", typeof(int), typeof(ExSlider), new PropertyMetadata(16));
//已选择刻度
public ImageSource DecreaseImage
{
get { return (ImageSource)GetValue(DecreaseImageProperty); }
set { SetValue(DecreaseImageProperty, value); }
}
// Using a DependencyProperty as the backing store for DecreaseImage. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DecreaseImageProperty =
DependencyProperty.Register("DecreaseImage", typeof(ImageSource), typeof(ExSlider), new PropertyMetadata(null));
public string DecreaseImagePath
{
get { return (string)GetValue(DecreaseImagePathProperty); }
set { SetValue(DecreaseImagePathProperty, value); }
}
// Using a DependencyProperty as the backing store for DecreaseImagePath. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DecreaseImagePathProperty =
DependencyProperty.Register("DecreaseImagePath", typeof(string), typeof(ExSlider), new PropertyMetadata(DescreaseImageCallBack));
public static void DescreaseImageCallBack(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
if (o is ExSlider)
{
(o as ExSlider).SetToImage((string)e.NewValue);
}
}
private void SetToImage(string value)
{
this.DecreaseImage = Helper.BuildUrl(value);
}
public Brush ThumbImage
{
get { return (Brush)GetValue(ThumbImageProperty); }
set { SetValue(ThumbImageProperty, value); }
}
// Using a DependencyProperty as the backing store for ThumbImage. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ThumbImageProperty =
DependencyProperty.Register("ThumbImage", typeof(Brush), typeof(ExSlider), new PropertyMetadata(null));
}
}