wpf自定义控件之双滑块Slider

效果

<UserControl x:Class="WpfApp1.SilderArrange"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Name="UC_Arrange" Loaded="UC_Arrange_Loaded">
    <StackPanel Orientation="Horizontal" Height="{Binding ElementName=UC_Arrange,Path=SilderHeight}" >
        <TextBox Text="{Binding  ElementName=SL_Bat1,Path=Value,Mode=TwoWay}"
                 KeyUp="TextBox_KeyUp1" 
                 Width="35"
                 Margin="0,3" BorderBrush="CornflowerBlue" />
        <Canvas Width="{Binding ElementName=UC_Arrange,Path=SilderWidth}" Margin="0,0,5,0">
            <Slider Name="SL_Bat1"
                Value="{Binding ElementName=UC_Arrange,Path=StartValue}"
                Minimum="{Binding ElementName=UC_Arrange,Path=Minimum}"
                Maximum="{Binding ElementName=UC_Arrange,Path=Maximum}"
                SelectionStart="{Binding ElementName=UC_Arrange,Path=StartValue}"
                SelectionEnd="{Binding ElementName=UC_Arrange,Path=EndValue}"
                Width="{Binding ElementName=UC_Arrange,Path=SilderWidth}"
                TickFrequency="{Binding ElementName=UC_Arrange,Path=SliderTickFrequency}"
                FocusVisualStyle="{x:Null}"
                IsSelectionRangeEnabled="True"
                TickPlacement="BottomRight"
                IsSnapToTickEnabled="True"
                VerticalAlignment="Center"
                Margin="2"
                ValueChanged="SL_Bat1_ValueChanged">
                <Slider.Clip>
                    <RectangleGeometry Rect="{Binding ElementName=UC_Arrange,Path=StartRect}" />
                </Slider.Clip>
            </Slider>
            <Slider Name="SL_Bat2"
                Value="{Binding ElementName=UC_Arrange,Path=EndValue}"
                Minimum="{Binding ElementName=UC_Arrange,Path=Minimum}"
                Maximum="{Binding ElementName=UC_Arrange,Path=Maximum}"
                SelectionStart="{Binding ElementName=UC_Arrange,Path=StartValue}"
                SelectionEnd="{Binding ElementName=UC_Arrange,Path=EndValue}"
                Width="{Binding ElementName=UC_Arrange,Path=SilderWidth}"
                TickFrequency="{Binding ElementName=UC_Arrange,Path=SliderTickFrequency}"
                FocusVisualStyle="{x:Null}"
                IsSelectionRangeEnabled="True"
                TickPlacement="BottomRight"
                IsSnapToTickEnabled="True"
                VerticalAlignment="Center"
                Margin="2"
                ValueChanged="SL_Bat2_ValueChanged">
                <Slider.Clip>
                    <RectangleGeometry Rect="{Binding ElementName=UC_Arrange,Path=EndRect}" />
                </Slider.Clip>
            </Slider>
        </Canvas>
        <TextBox   KeyUp="TextBox_KeyUp2" 
                  Text="{Binding  ElementName=SL_Bat2,Path=Value,Mode=TwoWay}"
                 Width="35" Margin="0,3"
                 BorderBrush="CornflowerBlue"/>
    </StackPanel>
</UserControl>
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 WpfApp1
{
    /// <summary>
    /// RangeControl.xaml 的交互逻辑
    /// </summary>
    public partial class SilderArrange : UserControl
    {
        #region 私有变量

        private static int _width = 150;  // 拖动条初始宽度
        private static int _height = 30;  // 高度
        private static int _min = 0;      // 最小值
        private static int _max = 255;    // 最大值
        private static int _freq = 10;    // 出现刻度的间距

        #endregion

        public SilderArrange()
        {
            InitializeComponent();
        }



        /// <summary>
        /// 裁剪矩阵(头)
        /// </summary>
        private Rect StartRect
        {
            get
            {
                return (Rect)GetValue(StartRectProperty);
            }
            set
            {
                SetValue(StartRectProperty, value);
            }
        }
        private static readonly DependencyProperty StartRectProperty =
          DependencyProperty.Register("StartRect", typeof(Rect), typeof(SilderArrange));

        /// <summary>
        /// 裁剪矩阵(尾)
        /// </summary>
        private Rect EndRect
        {
            get { return (Rect)GetValue(EndRectProperty); }
            set { SetValue(EndRectProperty, value); }
        }
        private static readonly DependencyProperty EndRectProperty =
            DependencyProperty.Register("EndRect", typeof(Rect), typeof(SilderArrange));



        #region 公开依赖属性

        /// <summary>
        /// 刻度间距,默认为10
        /// </summary>
        public int SliderTickFrequency
        {
            get { return (int)GetValue(SliderTickFrequencyProperty); }
            set { SetValue(SliderTickFrequencyProperty, value); }
        }
        public static readonly DependencyProperty SliderTickFrequencyProperty =
            DependencyProperty.Register("SliderTickFrequency", typeof(int), typeof(SilderArrange), new PropertyMetadata(_freq));

        /// <summary>
        /// 控件高度,默认为30
        /// </summary>
        public int SilderHeight
        {
            get { return (int)GetValue(SilderHeightProperty); }
            set { SetValue(SilderHeightProperty, value); }
        }
        public static readonly DependencyProperty SilderHeightProperty =
            DependencyProperty.Register("SilderHeight", typeof(int), typeof(SilderArrange), new PropertyMetadata(_height));

        /// <summary>
        /// 拖动条宽度,默认为150
        /// </summary>
        public int SilderWidth
        {
            get { return (int)GetValue(SilderWidthProperty); }
            set { SetValue(SilderWidthProperty, value); }
        }
        public static readonly DependencyProperty SilderWidthProperty =
             DependencyProperty.Register("SilderWidth", typeof(int), typeof(SilderArrange), new PropertyMetadata(_width));

        /// <summary>
        /// 最小值,默认为0
        /// </summary>
        public int Minimum
        {
            get { return (int)GetValue(MinimumProperty); }
            set { SetValue(MinimumProperty, value); }
        }
        public static readonly DependencyProperty MinimumProperty =
           DependencyProperty.Register("Minimum", typeof(int), typeof(SilderArrange), new PropertyMetadata(_min));

        /// <summary>
        /// 最大值,默认为100
        /// </summary>
        public int Maximum
        {
            get { return (int)GetValue(MaximumProperty); }
            set { SetValue(MaximumProperty, value); }
        }
        public static readonly DependencyProperty MaximumProperty =
            DependencyProperty.Register("Maximum", typeof(int), typeof(SilderArrange), new PropertyMetadata(_max));

        /// <summary>
        /// 选中开始值,默认为0
        /// </summary>
        public int StartValue
        {
            get { return (int)GetValue(StartValueProperty); }
            set { SetValue(StartValueProperty, value); }
        }
        public static readonly DependencyProperty StartValueProperty =
            DependencyProperty.Register("StartValue", typeof(int), typeof(SilderArrange));

        /// <summary>
        /// 选中结束值,默认为100
        /// </summary>
        public int EndValue
        {
            get { return (int)GetValue(EndValueProperty); }
            set { SetValue(EndValueProperty, value); }
        }
        public static readonly DependencyProperty EndValueProperty =
           DependencyProperty.Register("EndValue", typeof(int), typeof(SilderArrange), new PropertyMetadata(_max));

        #endregion

        #region 前台交互

        /// <summary>
        /// 对两个拖动条进行裁剪
        /// </summary>
        private void ClipSilder()
        {
            int selectedValue = EndValue - StartValue;
            int totalValue = Maximum - Minimum;
            double sliderClipWidth = SilderWidth * (StartValue - Minimum + selectedValue / 2) / totalValue;
            // 对第一个拖动条进行裁剪
            StartRect = new Rect(0, 0, sliderClipWidth, SilderHeight);
            // 对第二个拖动条进行裁剪
            EndRect = new Rect(sliderClipWidth, 0, SilderWidth, SilderHeight);
        }

        /// <summary>
        /// 初始化裁剪
        /// </summary>
        private void UC_Arrange_Loaded(object sender, RoutedEventArgs e)
        {
            ClipSilder();
        }


        private void SL_Bat1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (e.NewValue > EndValue)    // 检查值范围
                StartValue = EndValue;    // 超出,重设为最大值
            ClipSilder();
        }

        private void SL_Bat2_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (e.NewValue < StartValue)
                EndValue = StartValue;
            ClipSilder();
        }

        private void TextBox_KeyUp1(object sender, System.Windows.Input.KeyEventArgs e)
        {
            try
            {
                if (e.Key == Key.Enter)    // 按回车时确认输入
                    StartValue = Convert.ToInt32(((TextBox)sender).Text);
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void TextBox_KeyUp2(object sender, KeyEventArgs e)
        {
            try
            {
                if (e.Key == Key.Enter)
                    EndValue = Convert.ToInt32(((TextBox)sender).Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        #endregion

    }
}









 使用

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>

        <local:SilderArrange x:Name="SLA_V" SilderWidth="200" Minimum="0" Maximum="255"
                             HorizontalAlignment="Center"></local:SilderArrange>
        
    </Grid>
</Window>

 参考:

https://www.cnblogs.com/lekko/archive/2012/07/23/2604257.html

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将WPF Slider滑块变大,可以通过修改Slider的模板来实现。具体步骤如下: 1. 在XAML文件中,找到Slider的模板,可以通过右键Slider控件,选择Edit Template -> Edit a Copy来获取模板。 2. 在模板中找到Thumb元素,这个元素就是Slider滑块。 3. 修改Thumb元素的Width和Height属性,可以将滑块变大。例如,将Width和Height都设置为50,就可以将滑块变为正方形。 4. 保存模板,并将其应用到需要的Slider控件上即可。 下面是一个示例代码,演示如何将Slider滑块变大: ```xml <Slider Width="200" Height="30"> <Slider.Template> <ControlTemplate TargetType="Slider"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <TickBar x:Name="TopTick" Visibility="Collapsed" Fill="{TemplateBinding Foreground}" Placement="Top" Height="4"/> <TickBar x:Name="BottomTick" Visibility="Collapsed" Fill="{TemplateBinding Foreground}" Placement="Bottom" Height="4"/> <Border x:Name="TrackBackground" Background="#FFE9E9E9" Grid.Row="1" Height="4" CornerRadius="2"/> <Track x:Name="PART_Track" Grid.Row="1"> <Track.DecreaseRepeatButton> <RepeatButton Command="{x:Static Slider.DecreaseLarge}" Background="#FFE9E9E9"/> </Track.DecreaseRepeatButton> <Track.IncreaseRepeatButton> <RepeatButton Command="{x:Static Slider.IncreaseLarge}" Background="#FFE9E9E9"/> </Track.IncreaseRepeatButton> <Track.Thumb> <Thumb x:Name="Thumb" Width="50" Height="50" Background="{TemplateBinding Foreground}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Style="{DynamicResource SliderThumbStyle}"/> </Track.Thumb> </Track> </Grid> </ControlTemplate> </Slider.Template> </Slider> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值