当前位置: 移动技术网 > IT编程>开发语言>c# > c# Winform自定义控件-仪表盘功能

c# Winform自定义控件-仪表盘功能

2019年09月09日  | 移动技术网IT编程  | 我要评论

前提

入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。

github:https://github.com/kwwwvagaa/netwinformcontrol

码云:

nuget

install-package hzh_controls

目录

用处及效果

准备工作

依然使用gdi+画的,不懂的话就百度一下吧

另外主要用到了三角函数,如果不懂,可以向初中的数学老师再问问(你也可以百度一下)

开始

添加一个类ucmeter 继承 usercontrol

首先添加一个需要控制的属性

private int splitcount = 10;
     /// <summary>
     /// gets or sets the split count.
     /// </summary>
     /// <value>the split count.</value>
     [description("分隔刻度数量,>1"), category("自定义")]
     public int splitcount
     {
       get { return splitcount; }
      set
      {
        if (value < 1)
          return;
        splitcount = value;
        refresh();
      }
    }
    private int meterdegrees = 150;
    /// <summary>
    /// gets or sets the meter degrees.
    /// </summary>
    /// <value>the meter degrees.</value>
    [description("表盘跨度角度,0-360"), category("自定义")]
    public int meterdegrees
    {
      get { return meterdegrees; }
      set
      {
        if (value > 360 || value <= 0)
          return;
        meterdegrees = value;
        refresh();
      }
    }
    private decimal minvalue = 0;
    /// <summary>
    /// gets or sets the minimum value.
    /// </summary>
    /// <value>the minimum value.</value>
    [description("最小值,<maxvalue"), category("自定义")]
    public decimal minvalue
    {
      get { return minvalue; }
      set
      {
        if (value >= maxvalue)
          return;
        minvalue = value;
        refresh();
      }
    }
    private decimal maxvalue = 100;
    /// <summary>
    /// gets or sets the maximum value.
    /// </summary>
    /// <value>the maximum value.</value>
    [description("最大值,>minvalue"), category("自定义")]
    public decimal maxvalue
    {
      get { return maxvalue; }
      set
      {
        if (value <= minvalue)
          return;
        maxvalue = value;
        refresh();
      }
    }
    /// <summary>
    /// 获取或设置控件显示的文字的字体。
    /// </summary>
    /// <value>the font.</value>
    /// <permissionset>
    ///  <ipermission class="system.security.permissions.environmentpermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
    ///  <ipermission class="system.security.permissions.fileiopermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
    ///  <ipermission class="system.security.permissions.securitypermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" flags="unmanagedcode, controlevidence" />
    ///  <ipermission class="system.diagnostics.performancecounterpermission, system, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
    /// </permissionset>
    [description("刻度字体"), category("自定义")]
    public override font font
    {
      get
      {
        return base.font;
      }
      set
      {
        base.font = value;
        refresh();
      }
    }
    private decimal m_value = 0;
    /// <summary>
    /// gets or sets the value.
    /// </summary>
    /// <value>the value.</value>
    [description("值,>=minvalue并且<=maxvalue"), category("自定义")]
    public decimal value
    {
      get { return m_value; }
      set
      {
        if (value < minvalue || value > maxvalue)
          return;
        m_value = value;
        refresh();
      }
    }
    private metertextlocation textlocation = metertextlocation.none;
    /// <summary>
    /// gets or sets the text location.
    /// </summary>
    /// <value>the text location.</value>
    [description("值和固定文字显示位置"), category("自定义")]
    public metertextlocation textlocation
    {
      get { return textlocation; }
      set
      {
        textlocation = value;
        refresh();
      }
    }
    private string fixedtext;
    /// <summary>
    /// gets or sets the fixed text.
    /// </summary>
    /// <value>the fixed text.</value>
    [description("固定文字"), category("自定义")]
    public string fixedtext
    {
      get { return fixedtext; }
      set
      {
        fixedtext = value;
        refresh();
      }
    }
    private font textfont = defaultfont;
    /// <summary>
    /// gets or sets the text font.
    /// </summary>
    /// <value>the text font.</value>
    [description("值和固定文字字体"), category("自定义")]
    public font textfont
    {
      get { return textfont; }
      set
      {
        textfont = value;
        refresh();
      }
    }
    private color externalroundcolor = color.fromargb(255, 77, 59);
    /// <summary>
    /// gets or sets the color of the external round.
    /// </summary>
    /// <value>the color of the external round.</value>
    [description("外圆颜色"), category("自定义")]
    public color externalroundcolor
    {
      get { return externalroundcolor; }
      set
      {
        externalroundcolor = value;
        refresh();
      }
    }
    private color insideroundcolor = color.fromargb(255, 77, 59);
    /// <summary>
    /// gets or sets the color of the inside round.
    /// </summary>
    /// <value>the color of the inside round.</value>
    [description("内圆颜色"), category("自定义")]
    public color insideroundcolor
    {
      get { return insideroundcolor; }
      set
      {
        insideroundcolor = value;
        refresh();
      }
    }
    private color boundarylinecolor = color.fromargb(255, 77, 59);
    /// <summary>
    /// gets or sets the color of the boundary line.
    /// </summary>
    /// <value>the color of the boundary line.</value>
    [description("边界线颜色"), category("自定义")]
    public color boundarylinecolor
    {
      get { return boundarylinecolor; }
      set
      {
        boundarylinecolor = value;
        refresh();
      }
    }
    private color scalecolor = color.fromargb(255, 77, 59);
    /// <summary>
    /// gets or sets the color of the scale.
    /// </summary>
    /// <value>the color of the scale.</value>
    [description("刻度颜色"), category("自定义")]
    public color scalecolor
    {
      get { return scalecolor; }
      set
      {
        scalecolor = value;
        refresh();
      }
    }
    private color scalevaluecolor = color.fromargb(255, 77, 59);
    /// <summary>
    /// gets or sets the color of the scale value.
    /// </summary>
    /// <value>the color of the scale value.</value>
    [description("刻度值文字颜色"), category("自定义")]
    public color scalevaluecolor
    {
      get { return scalevaluecolor; }
      set
      {
        scalevaluecolor = value;
        refresh();
      }
    }
    private color pointercolor = color.fromargb(255, 77, 59);
    /// <summary>
    /// gets or sets the color of the pointer.
    /// </summary>
    /// <value>the color of the pointer.</value>
    [description("指针颜色"), category("自定义")]
    public color pointercolor
    {
      get { return pointercolor; }
      set
      {
        pointercolor = value;
        refresh();
      }
    }
    private color textcolor = color.fromargb(255, 77, 59);
    /// <summary>
    /// gets or sets the color of the text.
    /// </summary>
    /// <value>the color of the text.</value>
    [description("值和固定文字颜色"), category("自定义")]
    public color textcolor
    {
      get { return textcolor; }
      set
      {
        textcolor = value;
        refresh();
      }
    }

    rectangle m_rectworking;

重绘

protected override void onpaint(painteventargs e)
     {
       base.onpaint(e);
       var g = e.graphics;
       g.setgdihigh();
       //外圆
       float fltstartangle = -90 - (meterdegrees) / 2 + 360;
       var r1 = new rectangle(m_rectworking.location, new size(m_rectworking.width, m_rectworking.width));
       g.drawarc(new pen(new solidbrush(externalroundcolor), 1), r1, fltstartangle, meterdegrees);
       //内圆
       var r2 = new rectangle(m_rectworking.left + (m_rectworking.width - m_rectworking.width / 4) / 2, m_rectworking.top + (m_rectworking.width - m_rectworking.width / 4) / 2, m_rectworking.width / 4, m_rectworking.width / 4);
       g.drawarc(new pen(new solidbrush(insideroundcolor), 1), r2, fltstartangle, meterdegrees);
       //边界线
       if (meterdegrees != 360)
       {
         float fltangle = fltstartangle - 180;
         float inty = (float)(m_rectworking.top + m_rectworking.width / 2 - ((m_rectworking.width / 2 - m_rectworking.width / 8) * math.sin(math.pi * (fltangle / 180.00f))));
         float intx = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - m_rectworking.width / 8) * math.cos(math.pi * (fltangle / 180.00f)))));
         float flty1 = (float)(m_rectworking.top + m_rectworking.width / 2 - (m_rectworking.width / 8 * math.sin(math.pi * (fltangle / 180.00f))));
         float fltx1 = (float)(m_rectworking.left + (m_rectworking.width / 2 - (m_rectworking.width / 8 * math.cos(math.pi * (fltangle / 180.00f)))));
         g.drawline(new pen(new solidbrush(boundarylinecolor), 1), new pointf(intx, inty), new pointf(fltx1, flty1));
         g.drawline(new pen(new solidbrush(boundarylinecolor), 1), new pointf(m_rectworking.right - (fltx1 - m_rectworking.left), flty1), new pointf(m_rectworking.right - (intx - m_rectworking.left), inty));
       }
       //分割线
       int _splitcount = splitcount * 2;
       float fltsplitvalue = (float)meterdegrees / (float)_splitcount;
       for (int i = 0; i <= _splitcount; i++)
       {
         float fltangle = (fltstartangle + fltsplitvalue * i - 180) % 360;
         float flty1 = (float)(m_rectworking.top + m_rectworking.width / 2 - ((m_rectworking.width / 2) * math.sin(math.pi * (fltangle / 180.00f))));
         float fltx1 = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2) * math.cos(math.pi * (fltangle / 180.00f)))));
         float flty2 = 0;
         float fltx2 = 0;
         if (i % 2 == 0)
         {
           flty2 = (float)(m_rectworking.top + m_rectworking.width / 2 - ((m_rectworking.width / 2 - 10) * math.sin(math.pi * (fltangle / 180.00f))));
           fltx2 = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - 10) * math.cos(math.pi * (fltangle / 180.00f)))));
           if (!(meterdegrees == 360 && i == _splitcount))
           {
             decimal decvalue = minvalue + (maxvalue - minvalue) / _splitcount * i;
             var txtsize = g.measurestring(decvalue.tostring("0.##"), this.font);
             float fltfy1 = (float)(m_rectworking.top - txtsize.height / 2 + m_rectworking.width / 2 - ((m_rectworking.width / 2 - 20) * math.sin(math.pi * (fltangle / 180.00f))));
             float fltfx1 = (float)(m_rectworking.left - txtsize.width / 2 + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - 20) * math.cos(math.pi * (fltangle / 180.00f)))));
             g.drawstring(decvalue.tostring("0.##"), font, new solidbrush(scalevaluecolor), fltfx1, fltfy1);
           }
         }
         else
         {
           flty2 = (float)(m_rectworking.top + m_rectworking.width / 2 - ((m_rectworking.width / 2 - 5) * math.sin(math.pi * (fltangle / 180.00f))));
           fltx2 = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - 5) * math.cos(math.pi * (fltangle / 180.00f)))));
         }
         g.drawline(new pen(new solidbrush(scalecolor), i % 2 == 0 ? 2 : 1), new pointf(fltx1, flty1), new pointf(fltx2, flty2));
       }
       //值文字和固定文字
       if (textlocation != metertextlocation.none)
       {
         string str = m_value.tostring("0.##");
         var txtsize = g.measurestring(str, textfont);
         float flty = m_rectworking.top + m_rectworking.width / 4 - txtsize.height / 2;
         float fltx = m_rectworking.left + m_rectworking.width / 2 - txtsize.width / 2;
         g.drawstring(str, textfont, new solidbrush(textcolor), new pointf(fltx, flty));
         if (!string.isnullorempty(fixedtext))
         {
           str = fixedtext;
           txtsize = g.measurestring(str, textfont);
           flty = m_rectworking.top + m_rectworking.width / 4 + txtsize.height / 2;
           fltx = m_rectworking.left + m_rectworking.width / 2 - txtsize.width / 2;
           g.drawstring(str, textfont, new solidbrush(textcolor), new pointf(fltx, flty));
         }
       }
       //画指针
       g.fillellipse(new solidbrush(color.fromargb(100, pointercolor.r, pointercolor.g, pointercolor.b)), new rectangle(m_rectworking.left + m_rectworking.width / 2 - 10, m_rectworking.top + m_rectworking.width / 2 - 10, 20, 20));
       g.fillellipse(brushes.red, new rectangle(m_rectworking.left + m_rectworking.width / 2 - 5, m_rectworking.top + m_rectworking.width / 2 - 5, 10, 10));
       float fltvalueangle = (fltstartangle + ((float)(m_value - minvalue) / (float)(maxvalue - minvalue)) * (float)meterdegrees - 180) % 360;
       float intvaluey1 = (float)(m_rectworking.top + m_rectworking.width / 2 - ((m_rectworking.width / 2 - 30) * math.sin(math.pi * (fltvalueangle / 180.00f))));
       float intvaluex1 = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - 30) * math.cos(math.pi * (fltvalueangle / 180.00f)))));
       g.drawline(new pen(new solidbrush(pointercolor), 3), intvaluex1, intvaluey1, m_rectworking.left + m_rectworking.width / 2, m_rectworking.top + m_rectworking.width / 2);
     }

还有一个显示文字位置的枚举

 /// <summary>
   /// enum metertextlocation
   /// </summary>
   public enum metertextlocation
   {
     /// <summary>
     /// the none
     /// </summary>
     none,
     /// <summary>
     /// the top
     /// </summary>
     top,
     /// <summary>
     /// the bottom
     /// </summary>
     bottom
   }

代码就这么多了,看完整代码

// ***********************************************************************
// assembly     : hzh_controls
// created     : 2019-09-03
//
// ***********************************************************************
// <copyright file="ucmeter.cs">
//   copyright by huang zhenghui(黄正辉) all, qq group:568015492 qq:623128629 email:623128629@qq.com
// </copyright>
//
// blog: https://www.cnblogs.com/bfyx
// github:https://github.com/kwwwvagaa/netwinformcontrol
// gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
//
// if you use this code, please keep this note.
// ***********************************************************************
using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.windows.forms;
using system.drawing;
using system.drawing.drawing2d;
using system.componentmodel;
namespace hzh_controls.controls
{
  /// <summary>
  /// class ucmeter.
  /// implements the <see cref="system.windows.forms.usercontrol" />
  /// </summary>
  /// <seealso cref="system.windows.forms.usercontrol" />
  public class ucmeter : usercontrol
  {
    private int splitcount = 10;
    /// <summary>
    /// gets or sets the split count.
    /// </summary>
    /// <value>the split count.</value>
    [description("分隔刻度数量,>1"), category("自定义")]
    public int splitcount
    {
      get { return splitcount; }
      set
      {
        if (value < 1)
          return;
        splitcount = value;
        refresh();
      }
    }
    private int meterdegrees = 150;
    /// <summary>
    /// gets or sets the meter degrees.
    /// </summary>
    /// <value>the meter degrees.</value>
    [description("表盘跨度角度,0-360"), category("自定义")]
    public int meterdegrees
    {
      get { return meterdegrees; }
      set
      {
        if (value > 360 || value <= 0)
          return;
        meterdegrees = value;
        refresh();
      }
    }
    private decimal minvalue = 0;
    /// <summary>
    /// gets or sets the minimum value.
    /// </summary>
    /// <value>the minimum value.</value>
    [description("最小值,<maxvalue"), category("自定义")]
    public decimal minvalue
    {
      get { return minvalue; }
      set
      {
        if (value >= maxvalue)
          return;
        minvalue = value;
        refresh();
      }
    }
    private decimal maxvalue = 100;
    /// <summary>
    /// gets or sets the maximum value.
    /// </summary>
    /// <value>the maximum value.</value>
    [description("最大值,>minvalue"), category("自定义")]
    public decimal maxvalue
    {
      get { return maxvalue; }
      set
      {
        if (value <= minvalue)
          return;
        maxvalue = value;
        refresh();
      }
    }
    /// <summary>
    /// 获取或设置控件显示的文字的字体。
    /// </summary>
    /// <value>the font.</value>
    /// <permissionset>
    ///  <ipermission class="system.security.permissions.environmentpermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
    ///  <ipermission class="system.security.permissions.fileiopermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
    ///  <ipermission class="system.security.permissions.securitypermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" flags="unmanagedcode, controlevidence" />
    ///  <ipermission class="system.diagnostics.performancecounterpermission, system, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
    /// </permissionset>
    [description("刻度字体"), category("自定义")]
    public override font font
    {
      get
      {
        return base.font;
      }
      set
      {
        base.font = value;
        refresh();
      }
    }
    private decimal m_value = 0;
    /// <summary>
    /// gets or sets the value.
    /// </summary>
    /// <value>the value.</value>
    [description("值,>=minvalue并且<=maxvalue"), category("自定义")]
    public decimal value
    {
      get { return m_value; }
      set
      {
        if (value < minvalue || value > maxvalue)
          return;
        m_value = value;
        refresh();
      }
    }
    private metertextlocation textlocation = metertextlocation.none;
    /// <summary>
    /// gets or sets the text location.
    /// </summary>
    /// <value>the text location.</value>
    [description("值和固定文字显示位置"), category("自定义")]
    public metertextlocation textlocation
    {
      get { return textlocation; }
      set
      {
        textlocation = value;
        refresh();
      }
    }
    private string fixedtext;
    /// <summary>
    /// gets or sets the fixed text.
    /// </summary>
    /// <value>the fixed text.</value>
    [description("固定文字"), category("自定义")]
    public string fixedtext
    {
      get { return fixedtext; }
      set
      {
        fixedtext = value;
        refresh();
      }
    }
    private font textfont = defaultfont;
    /// <summary>
    /// gets or sets the text font.
    /// </summary>
    /// <value>the text font.</value>
    [description("值和固定文字字体"), category("自定义")]
    public font textfont
    {
      get { return textfont; }
      set
      {
        textfont = value;
        refresh();
      }
    }
    private color externalroundcolor = color.fromargb(255, 77, 59);
    /// <summary>
    /// gets or sets the color of the external round.
    /// </summary>
    /// <value>the color of the external round.</value>
    [description("外圆颜色"), category("自定义")]
    public color externalroundcolor
    {
      get { return externalroundcolor; }
      set
      {
        externalroundcolor = value;
        refresh();
      }
    }
    private color insideroundcolor = color.fromargb(255, 77, 59);
    /// <summary>
    /// gets or sets the color of the inside round.
    /// </summary>
    /// <value>the color of the inside round.</value>
    [description("内圆颜色"), category("自定义")]
    public color insideroundcolor
    {
      get { return insideroundcolor; }
      set
      {
        insideroundcolor = value;
        refresh();
      }
    }
    private color boundarylinecolor = color.fromargb(255, 77, 59);
    /// <summary>
    /// gets or sets the color of the boundary line.
    /// </summary>
    /// <value>the color of the boundary line.</value>
    [description("边界线颜色"), category("自定义")]
    public color boundarylinecolor
    {
      get { return boundarylinecolor; }
      set
      {
        boundarylinecolor = value;
        refresh();
      }
    }
    private color scalecolor = color.fromargb(255, 77, 59);
    /// <summary>
    /// gets or sets the color of the scale.
    /// </summary>
    /// <value>the color of the scale.</value>
    [description("刻度颜色"), category("自定义")]
    public color scalecolor
    {
      get { return scalecolor; }
      set
      {
        scalecolor = value;
        refresh();
      }
    }
    private color scalevaluecolor = color.fromargb(255, 77, 59);
    /// <summary>
    /// gets or sets the color of the scale value.
    /// </summary>
    /// <value>the color of the scale value.</value>
    [description("刻度值文字颜色"), category("自定义")]
    public color scalevaluecolor
    {
      get { return scalevaluecolor; }
      set
      {
        scalevaluecolor = value;
        refresh();
      }
    }
    private color pointercolor = color.fromargb(255, 77, 59);
    /// <summary>
    /// gets or sets the color of the pointer.
    /// </summary>
    /// <value>the color of the pointer.</value>
    [description("指针颜色"), category("自定义")]
    public color pointercolor
    {
      get { return pointercolor; }
      set
      {
        pointercolor = value;
        refresh();
      }
    }
    private color textcolor = color.fromargb(255, 77, 59);
    /// <summary>
    /// gets or sets the color of the text.
    /// </summary>
    /// <value>the color of the text.</value>
    [description("值和固定文字颜色"), category("自定义")]
    public color textcolor
    {
      get { return textcolor; }
      set
      {
        textcolor = value;
        refresh();
      }
    }
    rectangle m_rectworking;
    public ucmeter()
    {
      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);
      this.sizechanged += ucmeter1_sizechanged;
      this.autoscalemode = system.windows.forms.autoscalemode.none;
      this.size = new size(350, 200);
    }
    void ucmeter1_sizechanged(object sender, eventargs e)
    {
      m_rectworking = new rectangle(10, 10, this.width - 20, this.height - 20);
    }
    protected override void onpaint(painteventargs e)
    {
      base.onpaint(e);
      var g = e.graphics;
      g.setgdihigh();
      //外圆
      float fltstartangle = -90 - (meterdegrees) / 2 + 360;
      var r1 = new rectangle(m_rectworking.location, new size(m_rectworking.width, m_rectworking.width));
      g.drawarc(new pen(new solidbrush(externalroundcolor), 1), r1, fltstartangle, meterdegrees);
      //内圆
      var r2 = new rectangle(m_rectworking.left + (m_rectworking.width - m_rectworking.width / 4) / 2, m_rectworking.top + (m_rectworking.width - m_rectworking.width / 4) / 2, m_rectworking.width / 4, m_rectworking.width / 4);
      g.drawarc(new pen(new solidbrush(insideroundcolor), 1), r2, fltstartangle, meterdegrees);
      //边界线
      if (meterdegrees != 360)
      {
        float fltangle = fltstartangle - 180;
        float inty = (float)(m_rectworking.top + m_rectworking.width / 2 - ((m_rectworking.width / 2 - m_rectworking.width / 8) * math.sin(math.pi * (fltangle / 180.00f))));
        float intx = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - m_rectworking.width / 8) * math.cos(math.pi * (fltangle / 180.00f)))));
        float flty1 = (float)(m_rectworking.top + m_rectworking.width / 2 - (m_rectworking.width / 8 * math.sin(math.pi * (fltangle / 180.00f))));
        float fltx1 = (float)(m_rectworking.left + (m_rectworking.width / 2 - (m_rectworking.width / 8 * math.cos(math.pi * (fltangle / 180.00f)))));
        g.drawline(new pen(new solidbrush(boundarylinecolor), 1), new pointf(intx, inty), new pointf(fltx1, flty1));
        g.drawline(new pen(new solidbrush(boundarylinecolor), 1), new pointf(m_rectworking.right - (fltx1 - m_rectworking.left), flty1), new pointf(m_rectworking.right - (intx - m_rectworking.left), inty));
      }
      //分割线
      int _splitcount = splitcount * 2;
      float fltsplitvalue = (float)meterdegrees / (float)_splitcount;
      for (int i = 0; i <= _splitcount; i++)
      {
        float fltangle = (fltstartangle + fltsplitvalue * i - 180) % 360;
        float flty1 = (float)(m_rectworking.top + m_rectworking.width / 2 - ((m_rectworking.width / 2) * math.sin(math.pi * (fltangle / 180.00f))));
        float fltx1 = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2) * math.cos(math.pi * (fltangle / 180.00f)))));
        float flty2 = 0;
        float fltx2 = 0;
        if (i % 2 == 0)
        {
          flty2 = (float)(m_rectworking.top + m_rectworking.width / 2 - ((m_rectworking.width / 2 - 10) * math.sin(math.pi * (fltangle / 180.00f))));
          fltx2 = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - 10) * math.cos(math.pi * (fltangle / 180.00f)))));
          if (!(meterdegrees == 360 && i == _splitcount))
          {
            decimal decvalue = minvalue + (maxvalue - minvalue) / _splitcount * i;
            var txtsize = g.measurestring(decvalue.tostring("0.##"), this.font);
            float fltfy1 = (float)(m_rectworking.top - txtsize.height / 2 + m_rectworking.width / 2 - ((m_rectworking.width / 2 - 20) * math.sin(math.pi * (fltangle / 180.00f))));
            float fltfx1 = (float)(m_rectworking.left - txtsize.width / 2 + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - 20) * math.cos(math.pi * (fltangle / 180.00f)))));
            g.drawstring(decvalue.tostring("0.##"), font, new solidbrush(scalevaluecolor), fltfx1, fltfy1);
          }
        }
        else
        {
          flty2 = (float)(m_rectworking.top + m_rectworking.width / 2 - ((m_rectworking.width / 2 - 5) * math.sin(math.pi * (fltangle / 180.00f))));
          fltx2 = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - 5) * math.cos(math.pi * (fltangle / 180.00f)))));
        }
        g.drawline(new pen(new solidbrush(scalecolor), i % 2 == 0 ? 2 : 1), new pointf(fltx1, flty1), new pointf(fltx2, flty2));
      }
      //值文字和固定文字
      if (textlocation != metertextlocation.none)
      {
        string str = m_value.tostring("0.##");
        var txtsize = g.measurestring(str, textfont);
        float flty = m_rectworking.top + m_rectworking.width / 4 - txtsize.height / 2;
        float fltx = m_rectworking.left + m_rectworking.width / 2 - txtsize.width / 2;
        g.drawstring(str, textfont, new solidbrush(textcolor), new pointf(fltx, flty));
        if (!string.isnullorempty(fixedtext))
        {
          str = fixedtext;
          txtsize = g.measurestring(str, textfont);
          flty = m_rectworking.top + m_rectworking.width / 4 + txtsize.height / 2;
          fltx = m_rectworking.left + m_rectworking.width / 2 - txtsize.width / 2;
          g.drawstring(str, textfont, new solidbrush(textcolor), new pointf(fltx, flty));
        }
      }
      //画指针
      g.fillellipse(new solidbrush(color.fromargb(100, pointercolor.r, pointercolor.g, pointercolor.b)), new rectangle(m_rectworking.left + m_rectworking.width / 2 - 10, m_rectworking.top + m_rectworking.width / 2 - 10, 20, 20));
      g.fillellipse(brushes.red, new rectangle(m_rectworking.left + m_rectworking.width / 2 - 5, m_rectworking.top + m_rectworking.width / 2 - 5, 10, 10));
      float fltvalueangle = (fltstartangle + ((float)(m_value - minvalue) / (float)(maxvalue - minvalue)) * (float)meterdegrees - 180) % 360;
      float intvaluey1 = (float)(m_rectworking.top + m_rectworking.width / 2 - ((m_rectworking.width / 2 - 30) * math.sin(math.pi * (fltvalueangle / 180.00f))));
      float intvaluex1 = (float)(m_rectworking.left + (m_rectworking.width / 2 - ((m_rectworking.width / 2 - 30) * math.cos(math.pi * (fltvalueangle / 180.00f)))));
      g.drawline(new pen(new solidbrush(pointercolor), 3), intvaluex1, intvaluey1, m_rectworking.left + m_rectworking.width / 2, m_rectworking.top + m_rectworking.width / 2);
    }
  }
  /// <summary>
  /// enum metertextlocation
  /// </summary>
  public enum metertextlocation
  {
    /// <summary>
    /// the none
    /// </summary>
    none,
    /// <summary>
    /// the top
    /// </summary>
    top,
    /// <summary>
    /// the bottom
    /// </summary>
    bottom
  }
}

最后的话

如果你喜欢的话,请到 点个星星吧

总结

以上所述是小编给大家介绍的c# winform自定义控件-仪表盘功能,希望对大家有所帮助

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网