首页 > 编程语言 >C# WinForm自定义仪表盘控件开发教程

C# WinForm自定义仪表盘控件开发教程

时间:2025-01-16 15:30:10浏览次数:3  
标签:控件 Browsable 自定义 C# return true public

学习上位机开发,自然离不开自定义控件开发。

Windows 窗体支持三种类型的用户定义的控件:复合控件、扩展控件和自定义控件。

这里的自定义控件主要是指基于GDI+技术实现控件的绘制,最终实现效果如下所示:

这个控件可以作为仪表盘数据显示,也可以作为进度条来使用。

一、项目创建

1、我们使用VS2022创建一个项目,项目模板选择Windows窗体控件库(.NET Framework)。

2、项目名称修改为xbd.MeterPlate,框架选择.NET Framework 4.6,点击创建即可。

3、项目创建完成后会自动创建一个自定义控件,将自定义控件名称改成MeterPlater。

二、实现思路

整个控件开发过程分成四个步骤:

1、绘制固定颜色的底圆

2、绘制渐变色的扇形

3、绘制一个与背景颜色相同的内圆

4、绘制显示文字

三、实现过程

1、我们将一些可以通过外部进行修改的封装成属性,具体代码如下所示:

//基础圆颜色
private Color baseColor = Color.FromArgb(93, 107, 15);
[Browsable(true)]
[Category("自定义属性")]
[Description("设置或获取基础圆颜色")]
public Color BaseColor
{
    get { return baseColor; }
    set
    {
        baseColor = value;
        this.Invalidate();
    }
}
//内圆颜色
private Color innerColor = Color.White;
[Browsable(true)]
[Category("自定义属性")]
[Description("设置或获取内圆颜色")]
public Color InnerColor
{
    get { return innerColor; }
    set
    {
        innerColor = value;
        this.Invalidate();
    }
}
//文本显示
private string titleName = "目标完成";
[Browsable(true)]
[Category("自定义属性")]
[Description("设置或获取标题文本显示")]
public string TitleName
{
    get { return titleName; }
    set
    {
        titleName = value;
        this.Invalidate();
    }
}
//文本字体
private Font titleFont = new Font("微软雅黑", 10.5f);
[Browsable(true)]
[Category("自定义属性")]
[Description("设置或获取标题文本字体")]
public Font TitleFont
{
    get { return titleFont; }
    set
    {
        titleFont = value;
        this.Invalidate();
    }
}
//数据字体
private Font valueFont = new Font("微软雅黑", 10.5f);
[Browsable(true)]
[Category("自定义属性")]
[Description("设置或获取数据字体")]
public Font ValueFont
{
    get { return valueFont; }
    set
    {
        valueFont = value;
        this.Invalidate();
    }
}
//圆环宽度
private int gapWidth = 25;
[Browsable(true)]
[Category("自定义属性")]
[Description("设置或获取圆环宽度")]
public int GapWidth
{
    get { return gapWidth; }
    set
    {
        gapWidth = value;
        this.Invalidate();
    }
}
//开始颜色
private Color startColor = Color.Blue;
[Browsable(true)]
[Category("自定义属性")]
[Description("设置或获取圆环开始颜色")]
public Color StartColor
{
    get { return startColor; }
    set
    {
        startColor = value;
        this.Invalidate();
    }
}
//结束颜色
private Color endColor = Color.Red;
[Browsable(true)]
[Category("自定义属性")]
[Description("设置或获取圆环结束颜色")]
public Color EndColor
{
    get { return endColor; }
    set
    {
        endColor = value;
        this.Invalidate();
    }
}
//最大值
private float maxValue = 1000.0f;
[Browsable(true)]
[Category("自定义属性")]
[Description("设置或获取最大值")]
public float MaxValue
{
    get { return maxValue; }
    set
    {
        maxValue = value;
        this.Invalidate();
    }
}
//实际值
private float actualValue = 600.0f;
[Browsable(true)]
[Category("自定义属性")]
[Description("设置或获取实际值")]
public float ActualValue
{
    get { return actualValue; }
    set
    {
        actualValue = value;
        this.Invalidate();
    }
}
//是否百分比显示
private bool isPercentShow = true;
[Browsable(true)]
[Category("自定义属性")]
[Description("设置或获取是否百分比显示")]
public bool IsPercentShow
{
    get { return isPercentShow; }
    set
    {
        isPercentShow = value;
        this.Invalidate();
    }
}
//单位
private string unit = string.Empty;
[Browsable(true)]
[Category("自定义属性")]
[Description("设置或获取单位显示")]
public string Unit
{
    get { return unit; }
    set
    {
        unit = value;
        this.Invalidate();
    }

2、绘制过程:绘制过程就是根据实现思路来实现,通过代码依次实现绘制基础圆、绘制扇形、绘制内圆、绘制文字,具体代码如下所示

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    //获取画布
    Graphics graphics = e.Graphics;
    //画布设置
    graphics.SmoothingMode = SmoothingMode.AntiAlias;
    graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
    graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
    graphics.CompositingQuality = CompositingQuality.HighQuality;
    //绘制基础圆
    Rectangle rectangle = new Rectangle(1, 1, this.Width - 2, this.Height - 2);
    graphics.FillEllipse(new SolidBrush(this.baseColor), rectangle);
    //绘制扇形
    graphics.FillPie(new LinearGradientBrush(rectangle, startColor, endColor, 150.0f, true), rectangle, -90, (actualValue / maxValue) * 360);
    //绘制内圆
    graphics.FillEllipse(new SolidBrush(this.innerColor), new Rectangle(1 + gapWidth, 1 + gapWidth, this.Width - 2 * (1 + gapWidth), this.Height - 2 * (1 + gapWidth)));
    //绘制文字
    //上半个矩形
    Rectangle rectangle1 = new Rectangle(0, 0, this.Width, this.Height / 2);
    StringFormat stringFormat = new StringFormat();
    stringFormat.Alignment = StringAlignment.Center;
    stringFormat.LineAlignment = StringAlignment.Far;
    graphics.DrawString(this.titleName, this.titleFont, new SolidBrush(this.ForeColor), rectangle1, stringFormat);
    //下半个矩形
    Rectangle rectangle2 = new Rectangle(0, this.Height / 2, this.Width, this.Height / 2);
    stringFormat = new StringFormat();
    stringFormat.Alignment = StringAlignment.Center;
    stringFormat.LineAlignment = StringAlignment.Near;
    //考虑显示的数据内容
    string showValue = string.Empty;
    //如果百分比显示
    if (isPercentShow)
    {
        showValue = this.maxValue <= 0 ? "0.0%" : Convert.ToInt32(actualValue / maxValue * 100) + "%";
    }
    else
    {
        showValue = this.actualValue.ToString() + this.unit;
    }
    graphics.DrawString(showValue, this.valueFont, new SolidBrush(this.ForeColor), rectangle2, stringFormat);
}

3、最后在构造方法中添加一些初始化设置样式的代码:

 public MeterPlate()
 {
     InitializeComponent();
     this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
     this.SetStyle(ControlStyles.DoubleBuffer, true);
     this.SetStyle(ControlStyles.ResizeRedraw, true);
     this.SetStyle(ControlStyles.Selectable, true);
     this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
     this.SetStyle(ControlStyles.UserPaint, true);
 }

4、运行程序,效果如下所示:

标签:控件,Browsable,自定义,C#,return,true,public
From: https://blog.csdn.net/qq_26303227/article/details/145177563

相关文章

  • 揭秘10种主流PLC在ModbusTCP通信中的速度表现!
    大家好!我是付工。通透!终于把ModbusRTU弄明白了这样看来,ModbusTCP协议太简单了太简单了!C#轻松实现Modbus通信前面给大家介绍了一系列关于Modbus和ModbusTCP的知识。今天给大家来实测一下,对于不同品牌的PLC或板卡实现ModbusTCP通信时,通信速度有多快。一、测试界面我们......
  • 用Python管理Docker容器:从`docker-py`到自动化部署的全面指南
    《PythonOpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门!解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界在现代软件开发和运维过程中,Docker容器化技术因其高效、轻量和可移植性而被广泛应用。Python作为一种灵活且功能强大的编程语言,通过docker-py......
  • 从 AI Coding 演进路径看通义灵码 AI 程序员的发布,让更多 idea 变成产品
    点击链接,回顾发布会:https://www.bilibili.com/video/BV1v6c9euESz/根据StackOverflow的一个开发者调查报告:2024年有62% 的开发者正在使用AI编码工具;根据IDC的一个调查报告,对于已经探索生成式AI的中国企业,有31% 的研发人员已经在使用代码生成产品。AI编码工具的使用人......
  • 解析function(_0x457ace, _0x349832) 即random出处
    function(_0x457ace,_0x349832){ _0x457ace=_0x457ace-0x18a; var_0x4c6e1a=_0x19971f[_0x457ace]; if(a0_0x457a['pIaRKj']===undefined){ var_0x2a073e=function(_0x3f86c9){ var_0x153ef8='abcdefghijklmnopqrstuvwxyzABCDEFGH......
  • 二次开发,在使用LangChain中的Tongyi模型进行流式输出streaming报错问题,官网框架的BUG
    在使用LangChain中的Tongyi模型进行流式输出时,按照官方的代码直接运行会报一个类型错误:TypeError:Additionalkwargskeyoutput_tokensalreadyexistsinleftdictandvaluehasunsupportedtype<class'int'>.​其指向的错误文件路径如下C:\Users\Chenhao\AppData\Lo......
  • php根据权重自定义排序
    <?php//支付列表数组$paymentList=[['name'=>'支付宝','info'=>'支持多种支付场景','weight'=>3],['name'=>'微信支付','info'=>'便捷的移动支付','wei......
  • VP Codeforces Round 911 (Div. 2)
    A.CoverinWater题意:有n个格子,有些格子是好的,有些是坏的,你要给好格子都装上水,你可以花费一点价值让一个格子有水,也可以把一个格子的水移到另一个格子,没有花费。如果一个格子是好格子并且两边的格子都有水,这个格子就会自己填满水。问最少花费让所有好格子有水。容易想到,如果......
  • 【Solon 框架】使用国产化框架 Solon Cloud Gateway 替换 Spring Gateway
    #国产化框架Solon说明在「使用国产化框架Solon的一些开发经验」中提到,我们只是在平台的一个应用开始使用Solon框架,并非一次性的完全替换。但随着soloncloudgateway官方版本发布,替换SpringGateway也成为可能,于是开始相关的替换工作。我们的网关主要提供了统计授权和......
  • springboot环境下的rokectMQ多数据源实现
    业务原因,需要在一个项目中与多方MQ进行业务通信;步骤一,复制一份RocketMQProperties配置文件,避免与原来的冲突packagecom.heit.road.web.config;importorg.apache.rocketmq.common.topic.TopicValidator;importjava.util.HashMap;importjava.util.Map;publicclassMu......
  • 【C++】开源:ImGui图形用户界面库配置与使用
    项目介绍项目Github地址:https://github.com/ocornut/imguiDearImGui(ImGui)是一个开源的、用C++编写的图形用户界面(GUI)库。它由OCornut创建,旨在为应用程序和工具提供创建用户界面的简单高效的方式。以下是DearImGui的一些主要特性和特点:1.即时模式GUI:ImGui遵循即......