C#自定義控制元件—儀表盤

郭恩硕發表於2024-09-04

C#使用者控制元件之儀表盤

如何讓溫度、溼度、壓力等有量程的監控值如儀表盤(DashBoard)一樣顯示?

思路(GDI繪圖):
定義屬性:(儀表盤的半徑、顏色、間隙;刻度圓的半徑、顏色、字型;指標的顏色、佔比;文字的字型、佔比;)
繪製圖形:(半圓、刻度、指標、中心、文字)


定義屬性(將以上屬性挨個敲完)

//量程屬性(Font、Color、Float、Int、String、Bool)
private float range = 180.0f;
[Browsable(true)]
[Category("佈局_G")]
[Description("量程")]
public float Range
{
    get { return range; }

    set
    {
        if (value < 0.0f) return;
        range = value; this.Invalidate();
    }
}


定義欄位

private Graphics g;    //畫布
private Pen p;         //筆-繪製線條、曲線
private SolidBrush sb; //筆(填充)-填充矩形、路徑
private int width;
private int height;

儀表盤外環

//畫外環的三個圓弧(DrawArc)
float angle = (180.0f - gapAngle * 2) / 3;   //定義角度
RectangleF rec = new RectangleF(10, 10, this.width - 20, this.width - 20);  //定義座標、寬、高
p = new Pen(colorCircle1, outThickness); 
g.DrawArc(p, rec, -180.0f, angle);  //第一個弧
p = new Pen(colorCircle2, outThickness);
g.DrawArc(p, rec, -180.0f + angle + gapAngle, angle);   //第二個弧
p = new Pen(colorCircle3, outThickness); 
g.DrawArc(p, rec, -180.0f + angle * 2.0f + gapAngle + 2.0f, angle);   //第三個弧


儀表盤刻度

g.TranslateTransform(this.width * 0.5f, this.width * 0.5f);
點選檢視程式碼
for (int i = 0; i < 4; i++)
{
    float actualAngle = -180.0f + 60.0f * i;
    double x1 = Math.Cos(actualAngle * Math.PI / 180);
    double y1 = Math.Sin(actualAngle * Math.PI / 180);
    float x = Convert.ToSingle(this.width * scaleProportion * 0.5f * x1);
    float y = Convert.ToSingle(this.width * scaleProportion * 0.5f * y1);

    StringFormat sf = new StringFormat();

    if (i > 1)
    {
        x = x - 60;
        sf.Alignment = StringAlignment.Far;
    }
    else
    {
        sf.Alignment = StringAlignment.Near;
    }

    //刻度的座標,寬,高
    rec = new RectangleF(x, y, 60, 20);
    sb = new SolidBrush(scaleColor);

    if (range % 6 == 0)
    {
        g.DrawString((range / 3 * i).ToString(), scaleFont, sb, rec, sf);
    }
    else
    {
        g.DrawString((range / 3 * i).ToString("f1"), scaleFont, sb, rec, sf);
    }
} 

儀表盤中心點

//畫中心(FillEllipse)
g.FillEllipse(new SolidBrush(pointColor), new RectangleF(-centerRadius, -centerRadius, centerRadius * 2.0f, centerRadius * 2.0f));

儀表盤指標

//畫指標(DrawLine)
p = new Pen(pointColor, 3.0f);  //定義指標顏色、寬度
float sweepAngle = currentValue / range * 180.0f; //劃過的角度
float z = this.width * 0.5f * scaleProportion - outThickness * 0.5f - 20.0f;  //指標長度
g.RotateTransform(90.0f); //預設開始角度
g.RotateTransform(sweepAngle);
g.DrawLine(p, new PointF(0, 0), new PointF(0, z));  //畫一條線

下標文字標籤

//寫文字(DrawString)
g.RotateTransform(-sweepAngle);
g.RotateTransform(-90.0f);  //指定初始角度
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
rec = new RectangleF(this.width * (-0.5f), this.height * textProportion - 0.5f * this.width, this.width, this.height * (1.0f - this.scaleProportion));
string val = TextPrefix + currentValue.ToString() + "" + textUnit ;  //指定字串
g.DrawString(val, textFont, new SolidBrush(textColor), rec, sf);  


最後生成(自定義各種監控值顯示)


End

相關文章