using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; 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 JNGWpfControlLibrary { /// <summary> /// 拖动条 /// </summary> public partial class JSlider : UserControl { //private bool hadIn = false; public JSlider() { InitializeComponent(); //hadIn = true; } /// <summary> /// 轨道背景色 /// </summary> public static readonly DependencyProperty TrackBackgroundProperty = DependencyProperty.Register("TrackBackground", typeof(SolidColorBrush), typeof(JSlider), new PropertyMetadata(new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFD6D6D6")), null)); //private static void TrackBackgroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) //{ // //var s = d as JSlider; // //(s.Resources["SliderThumb.Track.Background"] as SolidColorBrush).Color = s.TrackBackground.Color; //} /// <summary> /// 轨道背景色 /// </summary> public SolidColorBrush TrackBackground { get { return (SolidColorBrush)GetValue(TrackBackgroundProperty); } set { SetValue(TrackBackgroundProperty, value); } } /// <summary> /// 进度背景色 /// </summary> public static readonly DependencyProperty ValueBackgroundProperty = DependencyProperty.Register("ValueBackground", typeof(SolidColorBrush), typeof(JSlider), new PropertyMetadata(new SolidColorBrush(Colors.Blue), null)); //private static void ValueBackgroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) //{ // //var s = d as JSlider; // //(s.Resources["SliderThumb.Value.Background"] as SolidColorBrush).Color = s.ValueBackground.Color; //} /// <summary> /// 进度背景色 /// </summary> public SolidColorBrush ValueBackground { get { return (SolidColorBrush)GetValue(ValueBackgroundProperty); } set { SetValue(ValueBackgroundProperty, value); } } /// <summary> /// 轨道边框背景色 /// </summary> public static readonly DependencyProperty TrackBorderBrushProperty = DependencyProperty.Register("TrackBorderBrush", typeof(SolidColorBrush), typeof(JSlider), new PropertyMetadata(new SolidColorBrush(Colors.LightGray), null)); /// <summary> /// 轨道边框背景色 /// </summary> public SolidColorBrush TrackBorderBrush { get { return (SolidColorBrush)GetValue(TrackBorderBrushProperty); } set { SetValue(TrackBorderBrushProperty, value); } } /// <summary> /// 轨道总值 /// </summary> public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register("Maximum", typeof(double), typeof(JSlider), new PropertyMetadata(100d, null)); /// <summary> /// 轨道总值 /// </summary> public double Maximum { get { return (double)GetValue(MaximumProperty); } set { SetValue(MaximumProperty, value); } } /// <summary> /// 当前值 /// </summary> public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(JSlider), new PropertyMetadata(10d, null)); /// <summary> /// 当前值 /// </summary> public double Value { get { return (double)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } } //public static readonly DependencyProperty FloatVisibilityProperty = DependencyProperty.Register("FloatVisibility", typeof(Visibility), typeof(JSlider), new PropertyMetadata(Visibility.Hidden, FVChanged)); //private static void FVChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) //{ // var s = d as JSlider; // //s.Resources["FV"] = s.FloatVisibility; //} ///// <summary> ///// 当前值 ///// </summary> //public Visibility FloatVisibility //{ // get { return (Visibility)GetValue(FloatVisibilityProperty); } // set { SetValue(FloatVisibilityProperty, value); } //} /// <summary> /// 浮球不透明度 /// </summary> public static readonly DependencyProperty FloatOpacityProperty = DependencyProperty.Register("FloatOpacity", typeof(double), typeof(JSlider), new PropertyMetadata(1d, null)); /// <summary> /// 浮球不透明度 /// </summary> public double FloatOpacity { get { return (double)GetValue(FloatOpacityProperty); } set { SetValue(FloatOpacityProperty, value); } } /// <summary> /// 轨道高 /// </summary> public static readonly DependencyProperty TrackHeightProperty = DependencyProperty.Register("TrackHeight", typeof(double), typeof(JSlider), new PropertyMetadata(4d, null)); /// <summary> /// 轨道高 /// </summary> public double TrackHeight { get => (double)GetValue(TrackHeightProperty); set { SetValue(TrackHeightProperty, value); } } /// <summary> /// 轨道内边框 /// </summary> public static readonly DependencyProperty TrackBorderThicknessProperty = DependencyProperty.Register("TrackBorderThickness", typeof(Thickness), typeof(JSlider), new PropertyMetadata(new Thickness(1), null)); /// <summary> /// 轨道内边框 /// </summary> public Thickness TrackBorderThickness { get => (Thickness)GetValue(TrackBorderThicknessProperty); set { SetValue(TrackBorderThicknessProperty, value); } } /// <summary> /// 浮球半径 /// </summary> public static readonly DependencyProperty FloatRadiusProperty = DependencyProperty.Register("FloatRadius", typeof(double), typeof(JSlider), new PropertyMetadata(7d, null)); //private double FRTHeight { get; set; } = 15; ////private double FRTTemplateHeight { get; set; } //private static void FRChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) //{ // var js = d as JSlider; // //var s = js.Content as Slider; // //var t = s.Template.FindName("Thumb", s) as Thumb; // var AD = js.FloatRadius * 2; // js.FRTHeight = AD; // //var tgb = t.Template.FindName("grip", t) as Border; // //tgb.CornerRadius = new CornerRadius(js.FloatRadius); // //tgb.BorderThickness = new Thickness(js.FloatBorderThickness); //} /// <summary> /// 浮球半径 /// </summary> public double FloatRadius { get => (double)GetValue(FloatRadiusProperty); set { SetValue(FloatRadiusProperty, value); } } /// <summary> /// 浮球强调边框 /// </summary> public static readonly DependencyProperty FloatBorderThicknessProperty = DependencyProperty.Register("FloatBorderThickness", typeof(double), typeof(JSlider), new PropertyMetadata(1d, null)); //private Thickness _FloatBorderThickness { get; set; } = new Thickness(1); //private static void FBTChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) //{ // var js = d as JSlider; // js._FloatBorderThickness = new Thickness(js.FloatBorderThickness); //} /// <summary> /// 浮球强调边框 /// </summary> public double FloatBorderThickness { get => (double)GetValue(FloatBorderThicknessProperty); set { SetValue(FloatBorderThicknessProperty, value); } } public static readonly DependencyProperty FloatStressForegroundProperty = DependencyProperty.Register("FloatStressForeground", typeof(SolidColorBrush), typeof(JSlider), new PropertyMetadata(new SolidColorBrush(Colors.Gray), null)); public SolidColorBrush FloatStressForeground { get => (SolidColorBrush)GetValue(FloatStressForegroundProperty); set { SetValue(FloatStressForegroundProperty, value); } } public static readonly DependencyProperty FloatForegroundProperty = DependencyProperty.Register("FloatForeground", typeof(SolidColorBrush), typeof(JSlider), new PropertyMetadata(new SolidColorBrush(Colors.LightGray), null)); public SolidColorBrush FloatForeground { get => (SolidColorBrush)GetValue(FloatForegroundProperty); set { SetValue(FloatForegroundProperty, value); } } public static readonly DependencyProperty FloatFocusForegroundProperty = DependencyProperty.Register("FloatFocusForeground", typeof(SolidColorBrush), typeof(JSlider), new PropertyMetadata(new SolidColorBrush(Colors.Gray), null)); public SolidColorBrush FloatFocusForeground { get => (SolidColorBrush)GetValue(FloatFocusForegroundProperty); set { SetValue(FloatFocusForegroundProperty, value); } } public static readonly DependencyProperty FloatDragForegroundProperty = DependencyProperty.Register("FloatDragForeground", typeof(SolidColorBrush), typeof(JSlider), new PropertyMetadata(new SolidColorBrush(Colors.LightGray), null)); public SolidColorBrush FloatDragForeground { get => (SolidColorBrush)GetValue(FloatDragForegroundProperty); set { SetValue(FloatDragForegroundProperty, value); } } public static readonly DependencyProperty FloatUnabledForegroundProperty = DependencyProperty.Register("FloatUnabledForeground", typeof(SolidColorBrush), typeof(JSlider), new PropertyMetadata(new SolidColorBrush(Colors.WhiteSmoke), null)); public SolidColorBrush FloatUnabledForeground { get => (SolidColorBrush)GetValue(FloatUnabledForegroundProperty); set { SetValue(FloatUnabledForegroundProperty, value); } } public static readonly DependencyProperty TrackUnabledForegroundProperty = DependencyProperty.Register("TrackUnabledForeground", typeof(SolidColorBrush), typeof(JSlider), new PropertyMetadata(new SolidColorBrush(Colors.LightGray), null)); public SolidColorBrush TrackUnabledForeground { get => (SolidColorBrush)GetValue(TrackUnabledForegroundProperty); set { SetValue(TrackUnabledForegroundProperty, value); } } public static readonly DependencyProperty TrackUnabledBackgroundProperty = DependencyProperty.Register("TrackUnabledBackground", typeof(SolidColorBrush), typeof(JSlider), new PropertyMetadata(new SolidColorBrush(Colors.Gray), null)); public SolidColorBrush TrackUnabledBackground { get => (SolidColorBrush)GetValue(TrackUnabledBackgroundProperty); set { SetValue(TrackUnabledBackgroundProperty, value); } } public static readonly DependencyProperty TrackUnabledBorderBrushProperty = DependencyProperty.Register("TrackUnabledBorderBrush", typeof(SolidColorBrush), typeof(JSlider), new PropertyMetadata(new SolidColorBrush(Colors.Gray), null)); public SolidColorBrush TrackUnabledBorderBrush { get => (SolidColorBrush)GetValue(TrackUnabledBorderBrushProperty); set { SetValue(TrackUnabledBorderBrushProperty, value); } } public static readonly RoutedEvent DragStartedEvent = EventManager.RegisterRoutedEvent("DragStarted", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(JSlider)); public event RoutedEventHandler DragStarted { add { AddHandler(DragStartedEvent, value); } remove { RemoveHandler(DragStartedEvent, value); } } private void Slider_DragStarted(object sender, DragStartedEventArgs e) { RaiseEvent(new RoutedEventArgs(DragStartedEvent/*, "hhh"*/)); } public static readonly RoutedEvent DragCompletedEvent = EventManager.RegisterRoutedEvent("DragCompleted", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(JSlider)); public event RoutedEventHandler DragCompleted { add { AddHandler(DragCompletedEvent, value); } remove { RemoveHandler(DragCompletedEvent, value); } } private void Slider_DragCompleted(object sender, DragCompletedEventArgs e) { RaiseEvent(new RoutedEventArgs(DragCompletedEvent)); } private void TrackBackground_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { ////Track track = (sender as Border).Tag as Track; ////track.IsHitTestVisible = false; //Border father = sender as Border; ////if (e.ButtonState == MouseButtonState.Pressed) ////{ //double percent = e.GetPosition(father).X / father.ActualWidth; ////this.Value = Maximum * percent; //// //Track track = (sender as Border).Tag as Track; //// //track.Thumb.CaptureMouse(); //// //track.Thumb.CaptureMouse();mysl. //// RaiseEvent(e); ////} ////track.IsHitTestVisible = false; //this.Value = Maximum * percent; //Track track = (sender as Border).Tag as Track; //track.Value = Maximum * percent; ////MessageBox.Show(""); ////track.Thumb.CaptureMouse(); //t = track; } bool hc = false; private void border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { hc = Mouse.Capture(sender as Border); Border father = (sender as Border).Tag as Border; double percent = e.GetPosition(father).X / father.ActualWidth; Value = Maximum * percent; } private void border_MouseMove(object sender, MouseEventArgs e) { if (!hc) return; Border father = (sender as Border).Tag as Border; double percent = e.GetPosition(father).X / father.ActualWidth; Value = Maximum * percent; } private void border_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { hc = !Mouse.Capture(null); } } //[ValueConversion(typeof(int), typeof(string))] public class RadiusToDia : IValueConverter { /// <summary> /// 半径转直径 /// </summary> /// /// <param name="value">半径</param> /// <param name="targetType"></param> /// <param name="parameter">结果格外增加值</param> /// <param name="culture"></param> /// <returns></returns> /// <exception cref="NotImplementedException"></exception> public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return (double)value * 2 + (parameter == null ? 0 : (double)parameter); } public object? ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return null; } } public class CValue : IMultiValueConverter { /// <summary> /// 依次输入值,计算权重后相加 /// </summary> /// <param name="values"> /// 依次输入值 /// </param> /// <param name="targetType"></param> /// <param name="parameter"> /// 依次输入权重 /// </param> /// <param name="culture"></param> /// <returns></returns> /// <exception cref="NotImplementedException"></exception> public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { double CV = 0; double[] VS = values.Select(v => double.Parse(v.ToString())).ToArray(); double[] PS = parameter.ToString().Split(',').Select(v => double.Parse(v)).ToArray(); for (int i = 0; i < PS.Length; i++) { if ((i + 1) >= VS.Length) CV += PS[i]; else CV += VS[i] * PS[i]; } GridLength gridLength = new GridLength(CV, GridUnitType.Pixel); return CV; } public object[]? ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { return null; } } public class DoubleToThickness : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var d = (double)value; return new Thickness(d, 0, d, 0); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return null; } } }
<UserControl x:Name="_this" x:Class="JNGWpfControlLibrary.JSlider" 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:JNGWpfControlLibrary" xmlns:sys="clr-namespace:System;assembly=mscorlib" mc:Ignorable="d" d:DesignWidth="800" Foreground="{x:Null}" Height="15"> <Control.Resources> <!--<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>--> <local:RadiusToDia x:Key="RTD"/> <local:CValue x:Key="CV"/> <local:DoubleToThickness x:Key="DTT"/> <ControlTemplate x:Key="SliderThumbHorizontalDefault" TargetType="{x:Type Thumb}"> <Grid x:Name="Gthumb" VerticalAlignment="Center"> <Border x:Name="grip" Padding="0" Height="{TemplateBinding Height}" Width="{Binding ElementName=grip,Path=Height}" SnapsToDevicePixels="True" Background="{Binding FloatForeground}" BorderThickness="{Binding FloatBorderThickness}" BorderBrush="Transparent" CornerRadius="{Binding FloatRadius}"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter TargetName="grip" Property="Background" Value="{Binding FloatFocusForeground}"/> <Setter TargetName="grip" Property="BorderBrush" Value="{Binding FloatStressForeground}"/> </Trigger> <Trigger Property="IsDragging" Value="true"> <Setter TargetName="grip" Property="Background" Value="{Binding FloatDragForeground}"/> <Setter TargetName="grip" Property="BorderBrush" Value="Transparent"/> </Trigger> <Trigger Property="IsEnabled" Value="false"> <Setter TargetName="grip" Property="Background" Value="{Binding FloatUnabledForeground}"/> <Setter TargetName="grip" Property="BorderBrush" Value="Transparent"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> <ControlTemplate x:Key="SliderHorizontal" TargetType="{x:Type Slider}" > <Border Tag="{Binding ElementName=TrackBackground}" MouseLeftButtonDown="border_MouseLeftButtonDown" MouseLeftButtonUp="border_MouseLeftButtonUp" x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True" MouseMove="border_MouseMove"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto" MinHeight="{TemplateBinding MinHeight}"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Border x:Name="TrackBackground" Tag="{Binding ElementName=PART_Track}" Background="{Binding TrackBackground}" BorderBrush="{Binding TrackBorderBrush}" BorderThickness="{Binding TrackBorderThickness}" Height="{Binding TrackHeight}" Grid.Row="1" VerticalAlignment="center" Margin="{Binding FloatRadius,Converter={StaticResource DTT}}" PreviewMouseLeftButtonDown="TrackBackground_MouseLeftButtonDown" /> <!--<Border x:Name="m" BorderThickness="0" Grid.Row="1" Margin="5,0" Background="Blue" Width="{TemplateBinding Value}" Height="4"/>--> <ProgressBar x:Name="progressbar" Grid.Row="1" Margin="{Binding ElementName=TrackBackground,Path=Margin}" Height="{Binding TrackHeight}" BorderThickness="0" Foreground="{Binding ValueBackground}" Maximum="{TemplateBinding Maximum}" Value="{TemplateBinding Value}" Background="{x:Null}" BorderBrush="{x:Null}"/> <Track x:Name="PART_Track" Grid.Row="1" Maximum="{TemplateBinding Maximum}"> <!--<Track.DecreaseRepeatButton> <RepeatButton Command="{x:Static Slider.DecreaseLarge}"/> </Track.DecreaseRepeatButton> <Track.IncreaseRepeatButton> <RepeatButton Command="{x:Static Slider.IncreaseLarge}"/> </Track.IncreaseRepeatButton>--> <!--<Track.IncreaseRepeatButton > <RepeatButton Command="{x:Static Slider.IncreaseLarge}"/> </Track.IncreaseRepeatButton>--> <Track.Thumb> <Thumb x:Name="Thumb" Opacity="{Binding FloatOpacity}" Focusable="False" Height="{Binding FloatRadius,Converter={StaticResource RTD}}" Width="{Binding ElementName=Thumb,Path=Height}" BorderThickness="0" OverridesDefaultStyle="True" HorizontalAlignment="Left" IsHitTestVisible="True" VerticalAlignment="Center" Template="{StaticResource SliderThumbHorizontalDefault}" Margin="1,0,0,0"> </Thumb> </Track.Thumb> </Track> </Grid> </Border> <ControlTemplate.Triggers> <!--<Trigger Property="IsSelectionRangeEnabled" Value="true"> <Setter Property="Visibility" TargetName="PART_SelectionRange" Value="Visible"/> </Trigger>--> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Foreground" TargetName="progressbar" Value="{Binding TrackUnabledForeground}"/> <Setter Property="Background" TargetName="TrackBackground" Value="{Binding TrackUnabledBackground}"/> <Setter Property="BorderBrush" TargetName="TrackBackground" Value="{Binding TrackUnabledBorderBrush}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> <Style x:Key="SliderStyle1" TargetType="{x:Type Slider}"> <!--<Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/>--> <Setter Property="Template" Value="{StaticResource SliderHorizontal}"/> </Style> </Control.Resources> <Slider x:Name="mysl" IsMoveToPointEnabled="False" Style="{StaticResource SliderStyle1}" Maximum="{Binding Maximum}" Value="{Binding Value}" LargeChange="0" DataContext="{Binding ElementName=_this}" Thumb.DragStarted="Slider_DragStarted" Thumb.DragCompleted="Slider_DragCompleted"/> </UserControl>