WPF中自定义双滑块Slider

2023-05-16

项目中遇到需要双滑块的情况,可以网上的基本都是单滑块的样式和例子,但是双滑块的很少,后来终于在网上找到一个大神的帖子,通过修改和完善终于符合自己的需求,可后来再查看代码的时候好像又看不懂了,现在重新整理记录下来,以备后续查看。

WPF中的Slider,看他的模板那就很复杂,粗略的想MultiRangeSlider不就是几个滑块(Thumb),加几个矩形么,一个滑块对应两个矩形,滑块移动的时候,不就两边的矩形的宽度的变化么,矩形我们只想关注宽度变化,不想再去调整他的其实位置,用什么容器来装矩形呢,StackPanel,里面的对象总是首尾相连的嘛,可是要使Thumb能够水平移动,在StackPanel中显示不合适,那就放到Canvas中,然后把这两个容器使用Grid叠在一起,Canvas在上,就是下面这个样子

<Grid>
    <StackPanel Margin="15,0,15,0"
                x:Name="RangeContainer"
                Orientation="Horizontal">

    </StackPanel>
    <Canvas x:Name="ThumbContainer">
    </Canvas>
</Grid>

为了滑块好看,给滑块做个样式:

  <Style TargetType="local:ThumbEx">
            <Setter Property="Width" Value="30"></Setter>
            <Setter Property="Height" Value="100"></Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Thumb">
                        <Grid>
                            <StackPanel>
                                <Rectangle SnapsToDevicePixels="True"                           
                                           Height="55"
                                           RadiusX="1"
                                           RadiusY="1"
                                           StrokeThickness="10"
                                           Stroke="#FF158BCF"
                                           Fill="#FF158BCF"></Rectangle>
                            </StackPanel>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

而我自己的项目中,最终想实现的目标是这样的:

所以代码更改后就是这样。

<UserControl.Background>
        <ImageBrush ImageSource="1.png?x-oss-process=image/watermark,g_center,image_YXJ0aWNsZS9wdWJsaWMvd2F0ZXJtYXJrLnBuZz94LW9zcy1wcm9jZXNzPWltYWdlL3Jlc2l6ZSxQXzQwCg==,t_20"  Stretch="Uniform"/>
    </UserControl.Background>
    <UserControl.Resources>
        <Style TargetType="local:ThumbEx">
            <Setter Property="Width" Value="30"></Setter>
            <Setter Property="Height" Value="100"></Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Thumb">
                        <Grid>
                            <StackPanel>
                                <Rectangle SnapsToDevicePixels="True"                           
                                           Height="55"
                                           RadiusX="1"
                                           RadiusY="1"
                                           StrokeThickness="10"
                                           Stroke="#FF158BCF"
                                           Fill="#FF158BCF"></Rectangle>
                            </StackPanel>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>
    <Grid >
        <StackPanel Margin="15,0,15,0"                    
                    x:Name="RangeContainer"
                    Orientation="Horizontal">
        </StackPanel>
        <Canvas x:Name="ThumbContainer">
        </Canvas>
    </Grid>

为了多次调用方便,我们使用UserControl来自定义这个控件,当然得支持各种数据Binding啊,对于这个控件来说,我不需要知道外面是什么样的数据结构,我只需要知道我要展现多滑块需要哪些数据就行,所以得有一个描述Range的数据结构

public class RangeItem
{
    #region 字段
    private double _from;
    private double _to;
    private string _name;
    private double _maxDuration;
    private bool _isStatic;
    private double _duration;

    #endregion

    #region 属性
    public double From
    {
        get
        {
            return _from;
        }
        set
        {
            _from = value;
        }
    }

    public double To
    {
        get
        {
            return _to;
        }
        set
        {
            _to = value;
        }
    }

    /// <summary>
    /// 是否静止
    /// </summary>
    public bool IsStatic
    {
        get
        {
            return _isStatic;
        }
        set
        {
            _isStatic = value;
        }
    }

    public double Duration
    {
        get
        {
            return _duration;
        }
        set
        {
            _duration = value;
        }
    }

    public double MaxDuration
    {
        get
        {
            return _maxDuration;
        }
        set
        {
            _maxDuration = value;
        }
    }

    #endregion
}

重要的属性有From(起始值),To(结束值),MaxDuration(总长),

根据这一个数据,我们就能生成一个矩形。整个Slider的宽度是固定的,所以就可以根据(To-From)/MaxDuration*Slider长度,就能计算出这个矩形的宽度,直接加入StackPanel就行。

矩形加进去了,现在加滑块,因为滑块是在Canvas中的,所以他需要确切知道Canvas.Left附加属性,这个Left不就左边矩形的宽度么。在把滑块和左右两边的矩形关联起来,因为矩形的拖动事件需要实时去改变两边的矩形的宽度。

        private static double m_ThumbWidth;

        public void SetLeft(double length)
        {
            length = length / 100 * m_ThumbWidth - 15;
            Canvas.SetLeft(_thumbExs[0], length);
        }

        public void SetRight(double length)
        {
            length = length / 100 * m_ThumbWidth + 15;
            Canvas.SetRight(_thumbExs[1], length);
        }

要跟后端的数据绑定,也就是三个矩形的宽度关联

MultiSlider x:Name="mSlider" RangeItems="{Binding Items}"

下方就是加入滑块两端,也就是三个矩形的宽度

            #region 初始化滑块
            mSlider.ControlWidth = mSlider.Width;
            Items.Add(new RangeItem()
            {
                From = 0,
                To = 0,
                IsStatic = true,
                MaxDuration = 100
            });

            Items.Add(new RangeItem()
            {
                From = 0,
                To = 100,
                IsStatic = false,
                MaxDuration = 100
            });

            Items.Add(new RangeItem()
            {
                From = 100,
                To = 100,
                IsStatic = false,
                MaxDuration = 100
            });
            this.DataContext = this;
            #endregion

同时需要这段代码:

        #region 多滑块slider
        private ObservableCollection<RangeItem> _items = new ObservableCollection<RangeItem>();

        public ObservableCollection<RangeItem> Items
        {
            get
            {
                return _items;
            }
            set
            {
                _items = value;
            }
        }
        #endregion

基本就这样,暂时满足自己的需求,时间长了回头过来写,有些啥意思自己都有点弄不明白了,凑合着看

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WPF中自定义双滑块Slider 的相关文章

  • WPF 数据绑定 - 对于具有验证规则的所有绑定,将 NotifyOnValidationError 设置为 true

    在我的 WPF 应用程序中 我想设置NotifyOnValidationError to true 框架默认为 false 对于所有子控件 绑定 如果它们有任何附加到绑定的 ValidationRules 事实上 最好也指定其他绑定默认值
  • 接收事件时闪烁选项卡标题

    我有一个基于选项卡的聊天应用程序 用户可以在不同的选项卡项目中与几个人聊天 我想通过闪烁选项卡标题来通知用户传入消息 以防用户正在与接收消息的选项卡以外的其他用户聊天 我如何在 WPF 中实现这一目标 一些例子将非常有用 此致 莫尔泰萨 您
  • StockTrader RI > 控制器、演示者,WTF?

    我目前正在学习如何通过 Prism 复合 WPF 项目高级使用 WPF 我观看了很多视频和示例 演示应用程序 StockTraderRI 让我提出了这个问题 以下各部分的具体作用是什么 SomethingService 好的 这是管理数据的
  • 双击数据网格时出现问题

    我的 C 代码中的数据网格有以下内容
  • 指定 Xaml 中开始标记和结束标记之间的属性

    考虑以下 Xaml
  • 列表框未虚拟化

    我有一个未虚拟化的列表框 我显然错过了一些东西 但找不到它 它实际上是一个列表框内的一个列表框 外部列表框有一个 ItemTemplate 其中包含一个 Expander Expander 用于显示一组项目 Expander 的内容是显示项
  • 如何将启动时窗口的位置定位到用户屏幕的右侧?

    我目前正在用 C 创建一个类似侧边栏的 WPF 应用程序 当用户启动应用程序时 我希望窗口自动将其自身定位到用户屏幕的一侧 我尝试了一些方法和谷歌搜索 但没有找到任何帮助 这是我正在尝试做的事情的一个例子 http prntscr com
  • DataGrid 是 WPF 中的必需品吗?

    我看到很多讨论正在进行 人们询问 WPF 的 DataGrid 并抱怨 Microsoft 迄今为止还没有在其 WPF 框架中提供 DataGrid 我们知道 WPF 是一项出色的 UI 技术 并且具有 ItemsControl DataT
  • 使用 MVVM 时 XamDataGrid 列可见性不起作用

    我正在尝试在 MVVM 架构中实现 XamDataGrid 列可见性 但它似乎不起作用 我正在执行以下操作 为未绑定字段添加可见性属性
  • 如何为 WPF 工具包图表提供样式

    我在 WPF 应用程序中使用 WPF Toolkit Chart 和 PieChart 我想将饼图图片中的默认白色背景更改为透明 如何提供风格来实现这一目标 WPF 旨在允许您通过 XAML 设置控件样式 不是代码 还可以通过样式使饼图中的
  • C# WPF - 应用程序图标 + ShowInTaskbar = False

    我创建了一个具有以下属性的自定义分层 WPF 窗口 允许透明度 True 在任务栏显示 False 背景 透明 最上面 True 图标 图标 ico 我已在 项目属性 gt 应用程序 选项卡下添加了 Icon ico 如果 ShowInTa
  • Wpf ScrollViewer 滚动量

    是否可以更改 WPF ScrollViewer 滚动的量 我只是想知道是否可以更改滚动查看器 以便在使用鼠标滚轮或滚动查看器箭头时可以更改增量滚动量 简短的答案是 如果不编写一些自定义滚动代码 就无法做到这一点 但不要让这吓到你 这并不那么
  • 给 MVVM 中的 View 一些命令

    假设我有一些用户控制权 用户控件有一些子窗口 用户控制用户想要关闭某种类型的子窗口 用户控制代码后面有一个方法 public void CloseChildWindows ChildWindowType type 但我无法调用此方法 因为我
  • 如何重新启动 WPF 应用程序?

    如何从代码重新启动 WPF 应用程序 在 Windows 窗体中存在 Application Restart 但出于某种原因 Microsoft 决定不在 WPF 中添加此方法 我讨厌 WPF 和 Windows 窗体之间的不兼容 喜欢 w
  • ListView选择单个项目,wpf

    我有一个列表视图 它的项目源是一个列表 我希望用户只选择一项 当我将列表视图的 SelectionMode 设置为 single 时 用户仍然可以选择多个项目 并且列表视图似乎变得疯狂并选择用户未选择的项目 看起来很奇怪 任何人都知道可能是
  • 快速变化的集合 MVVM WPF - 高 CPU 使用率和 UI 几乎冻结

    我正在开发一个带有数据网格的应用程序 它显示某些正在运行的 Windows 进程 在我的示例 Chrome 进程中 当选中复选框时 数据网格会加载进程 要求 显示每个进程的名称 内存使用情况 私有工作集 的 实时 信息 就像在 Window
  • 文本框的自定义日期格式

    有关的 将3个文本框绑定在一起 相同的日期时间不同的格式 https stackoverflow com questions 35581427 binding 3 textboxes together same datetime diffe
  • 绑定到后面代码中的相对源

    在我的 UserControl 中 我的 XAML 中有以下代码
  • 如何创建一个 WordPress 主页滑块,其中包含来自 4 个独特类别的最新或精选帖子的多个查询?

    我正在为我正在构建的 WordPress 网站创建一个滑块 我尝试构建的滑块共有 4 个幻灯片 框架 每个框架都需要显示特定类别中的最新帖子或特定类别中的特色帖子 我的意思是 4 张幻灯片 框架中的每张都代表一个单独的类别 Slide Fr
  • 如何让窗口最大化时所有控件按比例调整大小?

    当我单击最大化按钮时 窗口最大化 但控件未按比例调整大小 使控件相应调整大小的最佳方法是什么 我正在使用MVVM 这是我的代码

随机推荐

  • 计算机业务学习心得体会及辅助资料

    教师业务学习心得体会 我校在2019年年末举行了一次全校性的教师业务学习活动 xff0c 在本次业务学习后业务水平取得了长足的进步和提升 xff0c 发现了一些不足 xff0c 获得了一些新的东西 xff0c 亦总结了一些心得和体会 xff
  • 归并排序 详解

    注 xff1a 内容 xff0c 图片来自于慕课网liuyubobobo老师的课程 官方代码链接 xff1a https github com liuyubobobo Play with Algorithms 算法复杂度 xff1a O x
  • 关于MSP432单片机的吐槽【2021电赛A题】

    一 选题 全国大学生电子设计竞赛刚刚完赛 xff0c 本人选做的是A题 xff1a 失真度测量装置 当时选题的时候看到它附带了说明 xff1a 一定要使用TI公司的MCU以及它的片内ADC xff0c 不得使用其他片外ADC 和数据采集模块
  • 实现TCP并发服务器---IO多路复用

    实现TCP并发服务器 IO多路复用 1 服务器模型 1 1 概念 服务器模型主要分为两种 xff0c 循环服务器 xff0c 并发服务器 循环服务器 xff1a 服务器在同一时间只能处理一个客户端的请求 并发服务器 xff1a 服务器在同一
  • STM32串口发送中断踩坑

    今天想测试下Modbus设备 xff0c 手上暂时没有串口转485的模块 xff0c 就打算用手上的stm32f042的开发板做个串口转485模块 如下所示 但是软件实际开发过程中 xff0c 遇到了麻烦 现象 在打开串口接收中断时 xff
  • 十六进制转十进制(c语言)

    输入的十六进制数 xff0c 通过字符型存放在a 数组中 首先将字符型转为int型 xff08 将a转为10等等 xff09 存放在b 数组中 在与10 n相乘在相加得出结果 include lt stdio h gt include lt
  • 对视频图像进行OSD叠加

    频叠加就是将图片和文字信息叠加到视频信号中 xff0c 如电视台的LOGO xff0c 电影的字幕 xff0c 电视机的菜单 xff0c 都是通过视频叠加的形式显示在视频图像中的 区别于用于专业影视编辑行业的字幕叠加器 xff0c 字符叠加
  • VS2019 C#开发手机App环境配置和开发

    参考链接 xff1a https www dianyuan com eestar article 1284 html 上位机开发人员 xff0c 想开发APP xff0c 从头学Java xff0c 需要花的时间成本太大 xff0c 最近网
  • 华为手机通过ADB禁止系统更新和卸载自带软件

    参考链接 xff1a 电源网 刚买华为手机最烦的是每天都提示系统更新 xff0c 就算设置不提醒 xff0c 过两天又开始提醒 xff0c 不死不休 xff0c 最后还是一次手误最终还是让它得逞了 xff0c 自动更新了 xff0c 下面就
  • C#利用Socket实现C/S模式通信

    参考链接 xff1a https www dianyuan com eestar article 1330 html 首先我们要了解一下几点内容 xff1a 1 Tcp IP协议是什么 xff1f 2 Socket是什么 xff1f 3 s
  • OpenCV 图像处理 灰度化、二值化与加噪

    参考链接 xff1a https www dianyuan com eestar article 1414 html 因为要自动检测裂缝 xff0c 就考虑到了图像的二值化处理 xff0c 虽然C 可以实现二值化处理 xff0c 但是是逐个
  • ROC-RK3328-CC 开发板开箱和上手指南

    参考链接 xff1a https www dianyuan com eestar article 1424 html RK3328处理器采用了64位A53架构四核处理器 xff0c 主频为1 5GHz xff0c GPU则采用了Mali 4
  • C#中AForge库调节视频亮度、饱和度等属性

    参考链接 xff1a https www dianyuan com eestar article 1479 html 之前工作中需要调节摄像头的亮度 饱和度调节 xff0c 之前一直通过调用AForge的调节控件才能调节 xff0c 虽然可
  • Ubuntu下安装和配置Qtcreator5.15版本

    Qt选择 在官方的声明中 xff0c Qt5 15是Qt5 x的最后一个LTS版本 xff0c 增加了即将在2020年底推出的Qt6的部分新特性 xff0c 为了之后的新版本有更好的兼容性 xff0c 选择了Qt5 15 下载Qt 对于普通
  • python 获取文件夹下的文件名操作(两种)

    一 相对路径 文件存储的想对路径路径 path 61 39 data 0 39 os walk 是一个生成器 xff0c 返回三个值 xff1a 根目录 xff0c 根目录下的目录和文件列表 folder 61 os walk path 3
  • 1、串口(UART/COM/TTL/RS232/RS485)

    目录 串口简介 串行通讯制式 UART 2 1 简介 2 2 电平标准 TTL RS232 RS485 2 3 电平转换 xff08 重点讲解RS232 TTL xff09 USB转TTL USB转RS232 USB转RS485 RS232
  • 集成Python和QML

    Qt包括QML作为一种声明性地描述用户界面并使用JavaScript作为其中的脚本语言的手段 可以编写完整的独立QML应用程 序 xff0c 或将它们与C 43 43 结合使用 PyQt5允许QML以完全相同的方式与Python集成 特别是
  • 个人小型管理服务器 SVN的安装和使用方法

    1 下载TortoiseSVN客户端 官网下载地址 Downloads TortoiseSVN 注意下载跟你电脑位数匹配 64位 32位 的安装包 在页面的下面你还可以找到语言包 如图 下载完成后 应该有这些安装包 如图 接下来我们安装To
  • Ubuntu20.04下安装QtCreator 5.14.2(安装/卸载/创建快捷键/添加收藏)

    原文链接 xff1a https www dianyuan com eestar article 2864 html 都是自己原创 xff0c 发这里提高下知名度 xff0c 也帮助需要的人 一 Qt和Qt Creator的区别 Qt是C
  • WPF中自定义双滑块Slider

    项目中遇到需要双滑块的情况 xff0c 可以网上的基本都是单滑块的样式和例子 xff0c 但是双滑块的很少 xff0c 后来终于在网上找到一个大神的帖子 xff0c 通过修改和完善终于符合自己的需求 xff0c 可后来再查看代码的时候好像又