c# 自定义 滑块TrackBar

辛苦半天做出来的,如果觉得好用,记得点赞

效果图如下:

具体操作:

1 、添加代码(代码在下面),重新生成下整个工程,在工具栏中就出现控件,将控件拖到窗体中

2、只需要调整这些参数就行

3. 常用事件

4. 下面是代码 ,直接复制,将顶部 namespace 名改成你的工程名称就能用了 。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace 视频下载和播放
{
    public class LTrackBar : Control
    {
        public LTrackBar()
        {
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            CreateControl();
        }


        [Category("DemoUI"), Description("背景条颜色")]

        /// <summary>
        /// 未滑按钮
        /// </summary>
        private Color _BarButtonColor = Color.FromArgb(0, 0, 200); // 浅绿色
        public Color L_BarButtonColor
        {
            get { return _BarButtonColor; }
            set
            {
                _BarButtonColor = value;
                Invalidate();
            }
        }

        /// <summary>
        /// 未滑过的区域颜色
        /// </summary>
        private Color _BarColor = Color.FromArgb(128, 255, 128); // 浅绿色
        public Color L_BarColor
        {
            get { return _BarColor; }
            set{
                _BarColor = value;
                Invalidate();
            }
        }

        /// <summary>
        /// 已滑过的区域颜色
        /// </summary>
        private Color _SliderColor = Color.FromArgb(0, 200, 0); // 浅绿色
        public Color L_SliderColor
        {
            get { return _SliderColor; }
            set
            {
                _SliderColor = value;
                Invalidate();
            }
        }

        /// <summary>
        /// 圆角
        /// </summary>
        private bool _IsRound = true;
        public bool L_IsRound 
        {
            get { return _IsRound; }
            set {
                _IsRound = value;
                Invalidate();
            }
        }

        /// <summary>
        /// 最小值
        /// </summary>
        private int _Minimum = 0;
        public int L_Minimum {
            get { return _Minimum; }
            set {
                _Minimum = Convert.ToInt32(value);
                if (_Minimum >= _Maximum) { _Minimum = _Maximum - 1; }
                if (_Minimum < 0) { _Minimum = 0; }
                if (_Value < _Minimum) { _Value = _Minimum; }
                Invalidate();
            }
        }

        /// <summary>
        /// 最大值
        /// </summary>
        private int _Maximum = 100;
        public int L_Maximum
        {
            get { return _Maximum; }
            set
            {
                _Maximum = Convert.ToInt32(value);
                if (_Minimum >= _Maximum) { _Maximum = _Minimum + 1; }
                if (_Value > _Minimum) { _Value = _Minimum; }
                Invalidate();
            }
        }

        /// <summary>
        /// 添加 滑块值改变 委托事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public delegate void LValueChangedEventHandler(object sender, LEventArgs e);
        public event LValueChangedEventHandler LValueChanged;

        /// <summary>
        /// 滑块的当前值
        /// </summary>
        private int _Value = 0;
        public int L_Value {
            get { return _Value; }
            set {
                _Value = value;
                if (_Value > _Maximum) { _Value = _Maximum; }
                if (_Value < _Minimum) { _Value = _Minimum; }
                Invalidate();
                LValueChanged?.Invoke(this, new LEventArgs(_Value));
            }
        }

        /// <summary>
        /// 滑块的方向
        /// </summary>
        private Orientation _Orientation = Orientation.Horizontal_LR;
        public Orientation L_Orientation
        {
            get { return _Orientation; }
            set {
                Orientation old = _Orientation;
                _Orientation = value;

                if (old != _Orientation)
                {
                    Size = new Size(Size.Height, Size.Width);
                }
            }            
        }

        /// <summary>
        /// 滑块的高度
        /// </summary>
        private int _BarSize = 10;
        public int L_BarSize
        {
            get { return _BarSize; }
            set
            {
                _BarSize = value;
                if (_BarSize < 3) _BarSize = 3;
                if (_Orientation == Orientation.Horizontal_LR)
                {
                    Size = new Size(Width , _BarSize);
                }
                else
                { 
                    Size = new Size(_BarSize,Height);
                }
            }
        }

        /// <summary>
        /// 实现只能调整宽度/高度,需要重写SetBoundsCore方法
        /// </summary>
        protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
        {
            if (_Orientation == Orientation.Horizontal_LR)
                base.SetBoundsCore(x, y, width, _BarSize, specified);
            else
                base.SetBoundsCore(x, y, _BarSize, height, specified);
        }

        MouseStatus mouseStatus;
        private PointF mousePoint;
        
        /// <summary>
        /// 尺寸变化是刷新
        /// </summary>
        /// <param name="e"></param>
        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            pValueToPoint();
            e.Graphics.SmoothingMode = SmoothingMode.HighQuality;

            float barSizeRatio = 0.7f;
            if (_BarSize < 15)
                barSizeRatio = 0.5f;

            Pen penBarBack = new Pen(_BarColor, _BarSize * barSizeRatio);
            Pen penBarFore = new Pen(_SliderColor, _BarSize * barSizeRatio);

            float fCapWidth = _BarSize;
            float fCapHalfWidth = _BarSize / 2.0f;
            if (_IsRound)
            {      
                penBarBack.StartCap = LineCap.Round;
                penBarBack.EndCap = LineCap.Round;
                penBarFore.StartCap = LineCap.Round;
                penBarFore.EndCap = LineCap.Round;
            }

            float fPointValue = 0;
            if (_Orientation == Orientation.Horizontal_LR)
            {
                e.Graphics.DrawLine(penBarBack, fCapHalfWidth, Height / 2f, Width - fCapHalfWidth, Height / 2f);

                fPointValue = mousePoint.X;
                if (fPointValue < fCapHalfWidth) fPointValue = fCapHalfWidth;
                if (fPointValue > Width - fCapHalfWidth) fPointValue = Width - fCapHalfWidth;
            }
            else
            {
                e.Graphics.DrawLine(penBarBack, Width / 2f, fCapHalfWidth, Width / 2f, Height - fCapHalfWidth);

                fPointValue = mousePoint.Y;
                if (fPointValue < fCapHalfWidth) fPointValue = fCapHalfWidth;
                if (fPointValue > Height - fCapHalfWidth) fPointValue = Height - fCapHalfWidth;
            }

            Brush brush = new SolidBrush(_BarButtonColor);
            if (_Orientation == Orientation.Horizontal_LR)
            {
                e.Graphics.DrawLine(penBarFore, fCapHalfWidth, Height / 2f, fPointValue, Height / 2f);
                e.Graphics.FillEllipse(brush, fPointValue - fCapHalfWidth, Height / 2f - fCapHalfWidth, fCapWidth-1, fCapWidth-1);
            }
            else
            {
                e.Graphics.DrawLine(penBarFore, Width / 2f, fPointValue, Width / 2f, Height - fCapHalfWidth);
                e.Graphics.FillEllipse(brush, Width / 2f - fCapHalfWidth, fPointValue - fCapHalfWidth, fCapWidth-1, fCapWidth - 1);
            }
        }

        private void pValueToPoint()
        {
            float fCapWidth = _BarSize;
            float fCapHalfWidth = _BarSize / 2.0f;

            float fRatio = Convert.ToSingle(_Value - _Minimum) / (_Maximum - _Minimum);
            if (_Orientation == Orientation.Horizontal_LR)
            {
                float fPointValue = fRatio * (Width - fCapWidth) + fCapHalfWidth;
                mousePoint = new PointF(fPointValue, fCapHalfWidth);
            }
            else
            {
                float fPointValue = Height - fCapHalfWidth - fRatio * (Height - fCapWidth);
                mousePoint = new PointF(fCapHalfWidth, fPointValue);
            }
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            mouseStatus = MouseStatus.Down;
            mousePoint = e.Location;
            pPointToValue();
            Invalidate();
            base.OnMouseDown(e);     
        }
        
        protected override void OnMouseUp(MouseEventArgs e)
        {
            mouseStatus = MouseStatus.Up;
            base.OnMouseUp(e); 
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (mouseStatus == MouseStatus.Down)
            {
                mousePoint = e.Location;
                pPointToValue();
                Invalidate();
            }
            base.OnMouseMove(e);
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            mouseStatus = MouseStatus.Enter;
            base.OnMouseEnter(e);    
        }

        protected override void OnMouseLeave(EventArgs e)
        {           
            mouseStatus = MouseStatus.Leave;
            base.OnMouseLeave(e);
        }

        /// <summary>
        /// 计算滑块位置
        /// </summary>
        private void pPointToValue()
        {
            float fCapHalfWidth = 0;
            float fCapWidth = 0;

            if (_IsRound)
            {
                fCapWidth = _BarSize;
                fCapHalfWidth = _BarSize * 0.5f;
            }

            // 计算滑块的位置
            if (_Orientation == Orientation.Horizontal_LR)
            {
                float fRatio = Convert.ToSingle(mousePoint.X - fCapHalfWidth) / (Width - fCapWidth);
                _Value = Convert.ToInt32(fRatio * (_Maximum - _Minimum) + _Minimum);
            }
            else
            {
                float fRatio = Convert.ToSingle(Height - mousePoint.Y - fCapHalfWidth) / (Height - fCapWidth);
                _Value = Convert.ToInt32(fRatio * (_Maximum - _Minimum) + _Minimum);
            }

            if (_Value < _Minimum)
                _Value = _Minimum;
            else if (_Value > _Maximum)
                _Value = _Maximum;

            LValueChanged?.Invoke(this, new LEventArgs(_Value));
        }
    }

    public class LEventArgs : EventArgs
    {
        public LEventArgs(object value)
        {
            Value = value;
        }
    
        public object Value { get; set; }
    }




    /// <summary>
    /// 控件方向
    /// </summary>
    public enum Orientation
    { 
        /// <summary>
        /// 水平方向 (从左到右)
        /// </summary>
        Horizontal_LR,
        / <summary>
        / 水平方向 (从右到左)
        / </summary>
        //Horizontal_RL,
        /// <summary>
        /// 垂直方向 (从下到上)
        /// </summary>
        Vertical_BT,
        / <summary>
        /  垂直方向 (从上到下)
        / </summary>
        //Vertical_TB,
    }

    /// <summary>
    /// 鼠标状态
    /// </summary>
    public enum MouseStatus
    { 
        /// <summary>
        /// 鼠标进入
        /// </summary>
        Enter,
        /// <summary>
        /// 鼠标离开
        /// </summary>
        Leave,
        /// <summary>
        /// 鼠标按下
        /// </summary>
        Down,
        /// <summary>
        /// 鼠标放开
        /// </summary>
        Up
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/333321.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Qt5】QString的成员函数trimmed

2024年1月19日&#xff0c;周五下午 QString 的 trimmed 方法是用于移除字符串两端的空白字符&#xff08;空格、制表符、换行符等&#xff09;的方法。它返回一个新的字符串&#xff0c;该字符串是原始字符串去除两端空白后的结果。 下面是一个简单的示例&#xff1a; #incl…

瑞_Java开发手册_(六)工程结构

文章目录 工程结构的意义(一) 应用分层(二) 二方库依赖(三) 服务器 &#x1f64a;前言&#xff1a;本文章为瑞_系列专栏之《Java开发手册》的工程结构篇&#xff0c;主要介绍应用分层、二方库依赖、服务器。由于博主是从阿里的《Java开发手册》学习到Java的编程规约&#xff0c…

往docker中cloudbeaver的容器添加达梦数据库、impala数据库连接支持(cloudbeaver添加自定义数据连接)

cloudbeaver默认没有开放impala连接&#xff0c;更不会支持国产数据库了 docker安装运行cloudbeaver可以参考文章&#xff1a;docker安装运行CloudBeaver并设置默认语言为中文 本文跳过cloudbeaver镜像拉取&#xff0c;直接就开始实现自定义数据库连接功能 1、初始化cloudbe…

MLILY梦百合上榜“2023中国家居行业价值100公司”

2024年1月16日,由搜狐焦点家居联合搜狐财经、搜狐科技、搜狐时尚等主流频道主办的“2023中国家居行业价值100公司”榜单正式公布。MLILY梦百合作为头部睡眠科技品牌,经线上投票和专家评审,凭借强大的创新力、产品力、品牌力、服务力,从千家候选企业中脱颖而出,并最终荣获“2023…

TLP184(GR-TPL,SE 晶体管输出光电耦合器的特性与概述

TLP184(GR-TPL,SE 是一种交流输入型光电耦合器&#xff0c;由一个光电晶体管组成&#xff0c;该光电晶体管与两个砷化镓红外发射二极管光学耦合。 TLP184(GR-TPL,SE封装在非常小且薄的SO6封装中&#xff0c;具有高抗噪声性和高隔离电压。 由于TLP184(GR-TPL,SE比DIP封装更小&…

navigateTo失效-跳转不了页面解决办法!uniapp\vue

改了一个小时多的错误&#xff0c;跳转页面无论怎么样都跳转不了&#xff0c;有2个问题&#xff1a; 注意&#xff1a;uniapp的报错可以在console里检查&#xff01; 1.pages.json文件没有配置路径&#xff0c; 在pages:[ ]里面加 &#xff08;根据自己的路径进行修改 {&qu…

嵌入式操作教程:7-1 基于CMOS数字摄像头的灰度转换实验

一、实验目的 学习灰度转换的原理&#xff0c;掌握OV2640 摄像头和VPIF总线的工作原理&#xff0c;实现OV2640 摄像头采集图像并进行实时灰度转换显示在 LCD 上。 二、实验原理 OV2640摄像头 OV2640 是世界上第一个 1/4 英寸 2 百万像素视频传感器&#xff0c;同时是 OmniV…

SCSI/UFS储存架构/协议/电源管理/命令处理流程

UFS子系统架构 1.UFS协议 无论是ufs host controller部分还是ufs device部分&#xff0c;他们都将遵循统一的UFS规范 UFS Application Layer(UAP)应用层 1.UFS command set (UCS) UCS处理命令集&#xff0c;如读、写命令等&#xff0c;.使用的命令是简化的SCSI命令&#xff08;…

【01】mapbox js api加载arcgis切片服务

需求&#xff1a; 第三方的mapbox js api加载arcgis切片服务&#xff0c;同时叠加在天地图上&#xff0c;天地图坐标系web墨卡托。 效果图&#xff1a; 形如这种地址去加载http://zjq2022.gis.com:8080/demo/loadmapboxtdt.html 思路&#xff1a; 需要制作一个和天地图比例…

2023年度因子大盘点

基本信息: 指标说明: 2023年市场表现最佳 2023年市场单项最佳 2023年各分域最佳因子

【昇思技术公开课笔记-大模型】Bert理论知识

NLP中的预训练模型 语言模型演变经历的几个阶段 word2vec/Glove将离散的文本数据转换为固定长度的静态词向量&#xff0c;后根据下游任务训练不同的语言模型ELMo预训练模型将文本数据结合上下文信息&#xff0c;转换为动态词向量&#xff0c;后根据下游任务训练不同的语言模…

从数据到决策:项目管理和度量领域必备技能

0、引言 “效率”作为得物技术部的关键词之一&#xff0c;大家在研发效能、会议效率、协作效率、办公效率等方面一直进行着持续地探索。在实际落地的过程中&#xff0c;为了更好地评估应用效果&#xff0c;往往需要将定性描述转换为可量化的数据指标。这些数据指标可以帮助我们…

【大咖云集】2024年机械应用与机器视觉研究国际会议(ICMAMVR 2024)

2024年机械应用与机器视觉研究国际会议(ICMAMVR 2024) 2024 International Conference on Mechanical Applications and Machine Vision Research 数据库&#xff1a;EI,CPCI,CNKI,Google Scholar等检索 一、【会议简介】 2024年机械应用与机器视觉研究国际会议(ICMAMVR 2024)将…

C和指针课后答案

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 第八章课后答案 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参…

C语言:预处理详解

创作不易&#xff0c;来个三连呗&#xff01; 一、预定义符号 C语⾔设置了⼀些预定义符号&#xff0c;可以直接使⽤&#xff0c;预定义符号也是在预处理期间处理的。 __FILE__ //进⾏编译的源⽂件 __LINE__ //⽂件当前的⾏号 __DATE__ //⽂件被编译的⽇期 __TIME__ //⽂件被编…

python—01虚拟环境

文档结构 1、概念简介2、环境配置2.1、多版本解释器2.2、指令创建虚拟环境2.3、idea创建虚拟环境2.3.1、pycharm 1、概念简介 虚拟环境 在某些场景下&#xff0c;不同的项目需要基于不同版本的Python解释器来开发&#xff0c;或者不同的项目需要的第三方包或模块版本也不同。当…

【C语言编程之旅 5】刷题篇-if语句

第1题 解析 上述代码本来的想法应该是&#xff1a;循环10次&#xff0c;每次循环时如果i5则打印i的结果。 但if语句中表达式的写成了赋值&#xff0c;相当于每次循环尽量都是将i的值设置成了5&#xff0c;5为真&#xff0c;因此每次都会打印5 i每次修改成5打印后&#xff0c…

【面试突击】硬件级别可见性问题面试实战(上)

&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308; 欢迎关注公众号&#xff08;通过文章导读关注&#xff1a;【11来了】&#xff09;&#xff0c;及时收到 AI 前沿项目工具及新技术的推送&#xff01; 在我后台回复…

【LeetCode热题100】【子串】和为 K 的子数组

题目 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,1], k 2 输出&#xff1a;2示例 2&#xff1a; 输入&#xff1a;nums [1,…

DataSheet文件解读

DataSheet文件解读 IC介绍Features [特征]Typical Applications [典型应用]MARKING DIAGRAMS [标记图]![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/77041875f8f6435fa856a8f9aded6867.png)ORDERING INFORMATION 【订购信息】Figure1&#xff1a; Pin Diagram 【…