当前位置: 首页 > news >正文

C#绘制常用工业控件(仪表盘,流动条,开关等)

目录

1,使用Graphics绘制Toggle。

效果:

测试代码:

Toggle控件代码:

2,使用Graphics绘制Switch。

效果:

测试代码:

Switch控件代码:

3,使用Graphics绘制PanelHead。

效果

PanelHead控件代码:

4,自定义数字键盘NumberKeyBoard。

效果:

测试代码:

NumberKeyBoard控件代码

5,使用Graphics绘制LED。

效果:

LED控件代码:

6,使用Graphics绘制流动条。

效果:

FlowControl代码 :

7,使用Graphics绘制仪表盘1:

效果:

DashBoard控件代码

8,使用Graphics绘制仪表盘2:

效果:

Gague控件代码:


预览

1,使用Graphics绘制Toggle。

效果:

测试代码:
 private void toggle3_Click(object sender, EventArgs e){toggle3.Checked = !toggle3.Checked;}private void toggle2_Click(object sender, EventArgs e){toggle2.Checked = !toggle2.Checked;}private void toggle1_Click(object sender, EventArgs e){toggle1.Checked = !toggle1.Checked;}
Toggle控件代码:
 [DefaultEvent("Click")]//指定默认事件public partial class Toggle : UserControl{public Toggle(){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);}string falseText = "关闭";[Browsable(true), Category("自定义属性"), Description("false时文本")]public string FalseText{get{return falseText;}set{falseText = value;this.Invalidate();}}string trueText = "打开";[Browsable(true), Category("自定义属性"), Description("true时文本")]public string TrueText{get{return trueText;}set{trueText = value;this.Invalidate();}}bool _checked = false;[Browsable(true), Category("自定义属性"), Description("是否确认,Ture表示ON,False表示OFF")]public bool Checked{get{return _checked;}set{_checked = value;this.Invalidate();}}bool isShowWord = false;[Browsable(true), Category("自定义属性"), Description("是否显示文字,如果否则显示形状")]public bool IsShowWord{get{return isShowWord;}set{isShowWord = value;this.Invalidate();}}Color falseColor = Color.LightGray;[Browsable(true), Category("自定义属性"), Description("False状态时填充色")]public Color FalseColor{get{return falseColor;}set{falseColor = value;this.Invalidate();}}Color trueColor = Color.CadetBlue;[Browsable(true), Category("自定义属性"), Description("True状态时填充色")]public Color TrueColor{get{return trueColor;}set{trueColor = value;this.Invalidate();}}[Browsable(true), Category("自定义属性"), Description("若为非文字模式时,圆点的半径")]public int EmbellishRadius{get{return (int)(EmbellishRadiusFactor * Height);}}float _embellishRadiusFactor = 0.15f;[Browsable(true), Category("自定义属性"), Description("若为非文字模式时,圆点的比例因子")]public float EmbellishRadiusFactor{set{if (value >= 1 || value <= 0){_embellishRadiusFactor = 0.3f;}else{_embellishRadiusFactor = value;}this.Invalidate();}get{return _embellishRadiusFactor;}}bool _embellishPointAuto = true;[Browsable(true), Category("自定义属性"), Description("修饰文字或者图形的起点是否自动获取")]public bool EmbellishPointAuto{get{return _embellishPointAuto;}set{_embellishPointAuto = value;this.Invalidate();}}PointF _embellishPoint;[Browsable(true), Category("自定义属性"), Description("绘制修饰文字或者图形所需的起点")]public PointF EmbellishPoint{get{return _embellishPoint;}set{_embellishPoint = value;if (!EmbellishPointAuto){this.Invalidate();}}}Color _embellishColor = Color.White;[Browsable(true), Category("自定义属性"), Description("绘制修饰文字或者图形所需的颜色")]public Color EmbellishColor{get{return _embellishColor;}set{_embellishColor = value;this.Invalidate();}}ToggleType _toggleType = ToggleType.Rectangle;[Browsable(true), Category("自定义属性"), Description("Toggle的样式")]public ToggleType ToggleStyle{get{return _toggleType;}set{_toggleType = value;this.Invalidate();}}Padding _borderRadius = new Padding(3);[Browsable(true), Category("自定义属性"), Description("Rectangle风格时采用的倒角半径")]public Padding BorderRadius{get{return _borderRadius;}set{_borderRadius = value;if (ToggleStyle == ToggleType.Rectangle){this.Invalidate();}}}int _innerGap = 3;[Browsable(true), Category("自定义属性"), Description("内部间隙")]public int InnerGap{get{return _innerGap;}set{_innerGap = value;this.Invalidate();}}Color _slidingColor = Color.White;[Browsable(true), Category("自定义属性"), Description("滑动块颜色")]public Color SlidingColor{get{return _slidingColor;}set{_slidingColor = value;this.Invalidate();}}protected override void OnPaint(PaintEventArgs e){base.OnPaint(e);Graphics g = e.Graphics;g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;GraphicsPath path = new GraphicsPath();Padding drawingRadius;if (ToggleStyle == ToggleType.Ellipse){drawingRadius = new Padding(Height / 2);}else{drawingRadius = BorderRadius;}//绘制矩形//左上角path.AddArc(0, 0, drawingRadius.Left * 2, drawingRadius.Left * 2, 180, 90);//右上角path.AddArc(Width - drawingRadius.Top * 2, 0, drawingRadius.Top * 2, drawingRadius.Top * 2, 270, 90);//右下角path.AddArc(Width - drawingRadius.Right * 2, Height - drawingRadius.Right * 2, drawingRadius.Right * 2, drawingRadius.Right * 2, 0, 90);//左下角path.AddArc(0, Height - 2 * drawingRadius.Bottom, 2 * drawingRadius.Bottom, 2 * drawingRadius.Bottom, 90, 90);//滑动块起点Point slidingPoint;if (Checked){g.FillPath(new SolidBrush(TrueColor), path);slidingPoint = new Point(Width - Height + InnerGap, InnerGap);//如果是文字模式if (IsShowWord && EmbellishPointAuto){SizeF trueTextSize = g.MeasureString(TrueText, this.Font);EmbellishPoint = new PointF(((Width - trueTextSize.Width - Height)) / 2, ((Height - trueTextSize.Height)) / 2);}//如果是非文字模式if (!IsShowWord && EmbellishPointAuto){EmbellishPoint = new PointF(Height / 2 - EmbellishRadius, Height / 2 - EmbellishRadius);}}else{g.FillPath(new SolidBrush(FalseColor), path);slidingPoint = new Point(InnerGap, InnerGap);//如果是文字模式if (IsShowWord && EmbellishPointAuto){SizeF falseTextSize = g.MeasureString(FalseText, this.Font);EmbellishPoint = new PointF(Height + (Width - Height - falseTextSize.Width) / 2, ((Height - falseTextSize.Height)) / 2);}//如果是非文字模式if (!IsShowWord && EmbellishPointAuto){EmbellishPoint = new Point(Width - (Height / 2 + EmbellishRadius / 2), Height / 2 - EmbellishRadius);}}int slidingWidth = Height - 2 * InnerGap;GraphicsPath path2 = new GraphicsPath(FillMode.Alternate);int slidingHeight = slidingWidth;float scale = slidingWidth * 1.0f / Width;if (ToggleStyle == ToggleType.Rectangle){//左上角path2.AddArc(slidingPoint.X, slidingPoint.Y, drawingRadius.Left * 2, drawingRadius.Left * 2, 180, 90);//右上角path2.AddArc(slidingPoint.X + slidingWidth - drawingRadius.Top * 2, slidingPoint.Y, drawingRadius.Top * 2, drawingRadius.Top * 2, 270, 90);//右下角path2.AddArc(slidingPoint.X + slidingWidth - drawingRadius.Right * 2, slidingPoint.Y + slidingHeight - drawingRadius.Right * 2, drawingRadius.Right * 2, drawingRadius.Right * 2, 0, 90);//左下角path2.AddArc(slidingPoint.X, slidingPoint.Y + slidingHeight - 2 * drawingRadius.Bottom, 2 * drawingRadius.Bottom, 2 * drawingRadius.Bottom, 90, 90);}else{path2.AddEllipse(slidingPoint.X, slidingPoint.Y, Height - 2 * InnerGap, Height - 2 * InnerGap);}g.FillPath(new SolidBrush(SlidingColor), path2);if (IsShowWord){if (Checked){g.DrawString(TrueText, this.Font, new SolidBrush(this.EmbellishColor), EmbellishPoint);}else{g.DrawString(FalseText, this.Font, new SolidBrush(this.EmbellishColor), EmbellishPoint);}}else{g.DrawEllipse(new Pen(EmbellishColor, 2), new RectangleF(EmbellishPoint, new SizeF(EmbellishRadius * 2, EmbellishRadius * 2)));}}}public enum ToggleType{/// <summary>/// 矩形形状/// </summary>Rectangle,/// <summary>/// 椭圆形状/// </summary>Ellipse}

2,使用Graphics绘制Switch。

效果:

测试代码:
 private void switchControl1_Click(object sender, EventArgs e){switchControl1.SwitchStatus = !switchControl1.SwitchStatus;}
Switch控件代码:
 [DefaultEvent("Click")]public partial class SwitchControl : UserControl{public SwitchControl(){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);}int _outGap = 20;/// <summary>/// 外间隙/// </summary>[Browsable(true),Category("自定义属性"),Description("外间隙")]public int OutCap{get{return _outGap;}set{if (_outGap < 0){_outGap = 0;}else{_outGap = value;}this.Invalidate();}}int _innerGap = 3;/// <summary>/// 内间隙/// </summary>[Browsable(true), Category("自定义属性"), Description("内间隙")]public int InnerCap{get{return _innerGap;}set{if (_innerGap < 0){_innerGap = 0;}else{_innerGap = value;}this.Invalidate();}}bool _switchStatus = false;/// <summary>/// 开关状态/// </summary>[Browsable(true), Category("自定义属性"), Description("开关状态")]public bool SwitchStatus{get{return _switchStatus;}set{_switchStatus = value;this.Invalidate();}}int _outCircleWidth = 4;/// <summary>/// 外圆宽度/// </summary>[Browsable(true), Category("自定义属性"), Description("外圆宽度")]public int OutCircleWidth{get{return _outCircleWidth;}set{if (_outCircleWidth < 0){_outCircleWidth = 2;}else{_outCircleWidth = value;}this.Invalidate();}}Color _outCircleColor = Color.Gray;/// <summary>/// 外圆颜色/// </summary>[Browsable(true), Category("自定义属性"), Description("外圆颜色")]public Color OutCircleColor{get{return _outCircleColor;}set{_outCircleColor = value;this.Invalidate();}}Color _innerCircleColor = Color.Gray;/// <summary>/// 外圆颜色/// </summary>[Browsable(true), Category("自定义属性"), Description("内圆颜色")]public Color InnerCircleColor{get{return _innerCircleColor;}set{_innerCircleColor = value;this.Invalidate();}}/// <summary>///旋转手柄宽度/// </summary>[Browsable(true), Category("自定义属性"), Description("旋转手柄宽度")]public float HandleWidth{get{return Dimensions*HandleWidthFactor;}}float _handleWidthFactor = 0.1f;/// <summary>///旋转手柄宽度比例因子/// </summary>[Browsable(true), Category("自定义属性"), Description("旋转手柄宽度比例因子")]public float HandleWidthFactor{get{return _handleWidthFactor;}set{if (_handleWidthFactor < 0){_handleWidthFactor = 0.15f;}else{_handleWidthFactor = value;}this.Invalidate();}}Color _embellishColor = Color.Orange;/// <summary>/// 手柄标记颜色/// </summary>[Browsable(true), Category("自定义属性"), Description("手柄标记颜色")]public Color EmbellishColor{get{return _embellishColor;}set{_embellishColor = value;this.Invalidate();}}Color _handleColor = Color.Black;/// <summary>/// 手柄颜色/// </summary>[Browsable(true), Category("自定义属性"), Description("手柄颜色")]public Color HandleColor{get{return _handleColor;}set{_handleColor = value;this.Invalidate();}}/// <summary>/// 绘图的标准尺寸/// </summary>private int Dimensions{get{if (Width > Height){return Height;}else{return Width;}}}float _sweep = 36;/// <summary>/// 手柄旋转角度/// </summary>[Browsable(true), Category("自定义属性"), Description("手柄旋转角度")]public float Sweep{get{return _sweep;}set{_sweep = value;this.Invalidate();}}protected override void OnPaint(PaintEventArgs e){base.OnPaint(e);Graphics g = e.Graphics;g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;//绘制外圆g.DrawEllipse(new Pen(OutCircleColor, OutCircleWidth), OutCap, OutCap, this.Dimensions - 2 * OutCap, Dimensions - 2 * OutCap);//绘制内圆Point innerPoint = new Point(OutCap + OutCircleWidth + InnerCap, OutCap + OutCircleWidth + InnerCap);int innerWidth = Dimensions - 2 * innerPoint.X ;g.FillEllipse(new SolidBrush(InnerCircleColor), innerPoint.X, innerPoint.Y, innerWidth, innerWidth);//偏移原点g.TranslateTransform(Dimensions / 2, Dimensions / 2);//旋转角度if (SwitchStatus){g.RotateTransform(Sweep);}else{g.RotateTransform(-Sweep);}//绘制手柄g.FillRectangle(new SolidBrush(HandleColor), -HandleWidth/2, (-Dimensions + OutCap)/2, HandleWidth, Dimensions - OutCap);//绘制手柄标志float embellishWidth = HandleWidth / 2;float embellishHeight = HandleWidth * 1.5f;g.FillEllipse(new SolidBrush(EmbellishColor), -embellishWidth / 2, (-Dimensions + OutCap) / 2 + embellishWidth / 2, embellishWidth, embellishHeight);}}

3,使用Graphics绘制PanelHead。

效果

可设置边框颜色,有无,Header文字,Header高度,背景色等,以及Dock类型

PanelHead控件代码:
public partial class PanelHead : Panel{public PanelHead(){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);}private Color _headerBackgroundColor = Color.SkyBlue;[Browsable(true), Category("自定义属性"), Description("Header背景色")]public Color HeaderBackgroundColor{get { return _headerBackgroundColor; }set{_headerBackgroundColor = value;this.Invalidate();}}private int _headerHeight = 40;[Browsable(true), Category("自定义属性"), Description("Header高度")]public int HeaderHeight{get { return _headerHeight; }set{_headerHeight = value;this.Invalidate();}}private Color _headerForeColor = Color.Black;[Browsable(true), Category("自定义属性"), Description("Header前景色")]public Color HeaderForeColor{get { return _headerForeColor; }set{_headerForeColor = value;this.Invalidate();}}private string _headerText="标题";[Browsable(true), Category("自定义属性"), Description("Header前景色")]public string HeaderText{get { return _headerText; }set{_headerText = value;this.Invalidate();}}private Font _headerFont = DefaultFont;[Browsable(true), Category("自定义属性"), Description("Header文字字体")]public Font HeaderFont{get { return _headerFont; }set{_headerFont = value;this.Invalidate();}}private StringAlignment _headerTextAlignment = StringAlignment.Center;[Browsable(true), Category("自定义属性"), Description("Header文字水平对齐方式")]public StringAlignment HeaderTextAlignment{get { return _headerTextAlignment; }set{_headerTextAlignment = value;this.Invalidate();}}private StringAlignment _headerTextLineAlignment = StringAlignment.Center;[Browsable(true), Category("自定义属性"), Description("Header文字垂直对齐方式")]public StringAlignment HeaderTextLineAlignment{get { return _headerTextLineAlignment; }set{_headerTextLineAlignment = value;this.Invalidate();}}private bool _hasBorder = true;[Browsable(true), Category("自定义属性"), Description("是否有外边框")]public bool HasBorder{get { return _hasBorder; }set{_hasBorder = value;this.Invalidate();}}private Color _borderColor = Color.Black;[Browsable(true), Category("自定义属性"), Description("外边框颜色")]public Color BorderColor{get { return _borderColor; }set{_borderColor = value;this.Invalidate();}}private int _borderWidth = 1;[Browsable(true), Category("自定义属性"), Description("外边框的宽度")]public int BorderWidth{get { return _borderWidth; }set{_borderWidth = value;this.Invalidate();}}protected override void OnPaint(PaintEventArgs e){base.OnPaint(e);Graphics g = e.Graphics;g.SmoothingMode = SmoothingMode.AntiAlias; //使绘图质量最高,即消除锯齿g.InterpolationMode = InterpolationMode.HighQualityBicubic;g.CompositingQuality = CompositingQuality.HighQuality;g.FillRectangle(new SolidBrush(HeaderBackgroundColor), OriginPoint.X, OriginPoint.Y, DimensionsWidth, HeaderHeight);StringFormat format = new StringFormat(){Alignment = this.HeaderTextAlignment,LineAlignment = HeaderTextLineAlignment};g.DrawString(HeaderText, HeaderFont, new SolidBrush(HeaderForeColor), new RectangleF(OriginPoint.X, OriginPoint.Y, DimensionsWidth, HeaderHeight), format);//绘制边框if (HasBorder){g.DrawRectangle(new Pen(BorderColor, BorderWidth), BorderWidth / 2, BorderWidth / 2, Width - BorderWidth, Height - BorderWidth);}}int DimensionsWidth{get{if (HasBorder){return Width - BorderWidth-2;}return Width;}}int DimensionsHeight{get{if (HasBorder){return Height - BorderWidth-2;}return Height;}}Point OriginPoint{get{if (HasBorder){return new Point(BorderWidth, BorderWidth);}return new Point(0, 0);}}Dictionary<Control, Rectangle> dic = new Dictionary<Control, Rectangle>();int flag = 0xff;protected override void OnLayout(LayoutEventArgs e){if (HasChildren){foreach (Control item in this.Controls){switch (item.Dock){case DockStyle.None:item.SuspendLayout();if (dic.ContainsKey(item) && !((flag & 0x1) == 1)){item.Bounds = dic[item];flag = 0xff;}item.ResumeLayout();//  base.OnLayout(e);break;case DockStyle.Top:if ((flag & 0x1) == 1){dic[item] = item.Bounds;flag = flag & 0xfe;}if ((flag & 0x2) == 2){item.Bounds = dic[item];flag = flag & 0xfd;}item.SuspendLayout();if (item.Height <= DimensionsHeight - HeaderHeight){item.SetBounds(OriginPoint.X, OriginPoint.Y + HeaderHeight, DimensionsWidth, item.Height);}else{item.SetBounds(OriginPoint.X, OriginPoint.Y + HeaderHeight, DimensionsWidth, DimensionsHeight - HeaderHeight);}break;case DockStyle.Bottom:if ((flag & 0x1) == 1){dic[item] = item.Bounds;flag = flag & 0xfe;}if ((flag & 0x4) == 4){item.Bounds = dic[item];flag = flag & 0xfb;}item.SuspendLayout();if (item.Height <= DimensionsHeight - HeaderHeight){item.SetBounds(OriginPoint.X,OriginPoint.Y+ DimensionsHeight -item.Height, DimensionsWidth, item.Height);}else{item.SetBounds(OriginPoint.X, OriginPoint.Y + HeaderHeight, DimensionsWidth, DimensionsHeight - HeaderHeight);}break;case DockStyle.Left:if ((flag & 0x1) == 1){dic[item] = item.Bounds;flag = flag & 0xfe;}if ((flag & 0x8) == 8){item.Bounds = dic[item];flag = flag & 0xf7;}item.SuspendLayout();if (item.Width <= DimensionsWidth){item.SetBounds(OriginPoint.X, OriginPoint.Y + HeaderHeight, item.Width, DimensionsHeight - HeaderHeight);}else{item.SetBounds(OriginPoint.X, OriginPoint.Y + HeaderHeight, DimensionsWidth, Height - HeaderHeight);}break;case DockStyle.Right:if ((flag & 0x1) == 1){dic[item] = item.Bounds;flag = flag & 0xfe;}if ((flag & 0x10) == 16){item.Bounds = dic[item];flag = flag & 0xef;}item.SuspendLayout();if (item.Width <= DimensionsWidth){item.SetBounds(OriginPoint.X + DimensionsWidth - item.Width, OriginPoint.Y + HeaderHeight, item.Width, DimensionsHeight - HeaderHeight);}else{item.SetBounds(OriginPoint.X, OriginPoint.Y + HeaderHeight, DimensionsWidth, Height - HeaderHeight);}break;case DockStyle.Fill:if ((flag & 0x1) == 1){dic[item] = item.Bounds;flag = flag & 0xfe;}item.SuspendLayout();item.SetBounds(OriginPoint.X, OriginPoint.Y + HeaderHeight, DimensionsWidth, DimensionsHeight - HeaderHeight);break;default:break;}}}}}

4,自定义数字键盘NumberKeyBoard。

效果:

测试代码:
public Form2(){InitializeComponent();//接收输入完成的数据numKeyBoard1.InputCompleted += NumKeyBoard1_InputCompleted1;//Esc事件numKeyBoard1.InputCancel += NumKeyBoard1_InputCancel;}private void Form2_Load(object sender, EventArgs e){//注册哪些控件使用数字键盘,通过控件名进行注册,如果不注册将无数字键盘弹出numKeyBoard1.RegisterNumberKeyBoard(new string[] { "textBox1", "textBox2", "textBox3" });}private void NumKeyBoard1_InputCancel(object sender, EventArgs e){//键盘的打开是通过目的控件的GotFocus事件完成如果不将焦点转移到其他控件,将影响在该目的控件上重复打开键盘this.ActiveControl = button1;}private void NumKeyBoard1_InputCompleted1(object sender, CustomControl.NumKeyBoardEventArgs e){Control control = e.TargetControl;float value = e.Value;if(control is TextBox){control.Text = value.ToString();}this.ActiveControl=button1;}
NumberKeyBoard控件代码

 public partial class NumKeyBoard : UserControl{public NumKeyBoard(){InitializeComponent();InitLoad();}/// <summary>/// 数字键盘输入完成/// </summary>public event EventHandler<NumKeyBoardEventArgs> InputCompleted;/// <summary>/// 输入取消事件/// </summary>public event EventHandler InputCancel;List<Control> targetControls = new List<Control>();void InitLoad(){lblTitle.MouseMove += NumKeyBoard_MouseMove;lblTitle.MouseDown += NumKeyBoard_MouseDown;lblTitle.MouseUp += NumKeyBoard_MouseUp;foreach (Control item in tableLayoutKeyBoard.Controls){if (item is Button){(item as Button).Click += NumKeyBoard_Click;}}}Control curControl;private void TargetControl_GotFocus(object sender, EventArgs e){this.Visible = true;this.BringToFront();curControl = sender as Control;if (sender is TextBox){TextBox tb = sender as TextBox;lblDisplay.Text = tb.Text;//设置键盘出现位置Point tbPoint = tb.Location;Point p = new Point();if (tbPoint.Y + this.Height < tb.TopLevelControl.Height || tbPoint.Y < this.Height){p.Y = tbPoint.Y + 2 + tb.Height;}else{p.Y = tbPoint.Y - this.Height - 2;}if (this.Width > tb.TopLevelControl.Width - tbPoint.X){p.X = tbPoint.X + tb.Width - this.Width;}else{p.X = tbPoint.X + 2;}this.Location = p;}}#region 键盘移动Point offsetPoint;bool canMove = false;private void NumKeyBoard_MouseUp(object sender, MouseEventArgs e){canMove = false;}private void NumKeyBoard_MouseDown(object sender, MouseEventArgs e){if (e.Button == MouseButtons.Left){canMove = true;offsetPoint = new Point(-e.X, -e.Y);}}private void NumKeyBoard_MouseMove(object sender, MouseEventArgs e){if (canMove){Point curPoint = this.Parent.PointToClient(Control.MousePosition);curPoint.Offset(offsetPoint);this.Location = curPoint;}}#endregionprivate void NumKeyBoard_Click(object sender, EventArgs e){string key = (sender as Button).Text.Trim().ToLower();lblTitle.Text = "";switch (key){case "-":if (lblDisplay.Text.StartsWith("-")){lblDisplay.Text = lblDisplay.Text.Remove(0, 1);}else{lblDisplay.Text = lblDisplay.Text.Insert(0, "-");}break;case "del":if (lblDisplay.Text.Length > 0){lblDisplay.Text = lblDisplay.Text.Remove(lblDisplay.Text.Length - 1, 1);}break;case "esc":lblDisplay.Text = "";InputCancel?.Invoke(this, null);this.Visible = false;break;case ".":if (lblDisplay.Text.IndexOf('.') != -1){return;}if (string.IsNullOrEmpty(lblDisplay.Text)){lblDisplay.Text = "0.";return;}lblDisplay.Text += ".";break;case "0":if (lblDisplay.Text.Equals("0")){return;}lblDisplay.Text += "0";break;case "enter":try{float value = float.Parse(lblDisplay.Text.Trim());if (value < MinNum || value > MaxNum){lblTitle.Text = $"数值只能位于 {MinNum}~{MaxNum} 之间";System.Media.SystemSounds.Hand.Play();return;}lblDisplay.Text = "";InputCompleted?.Invoke(this, new NumKeyBoardEventArgs(curControl, value));this.Visible = false;}catch (Exception ex){lblTitle.Text = ex.Message;}break;default:if (lblDisplay.Text.Equals("0")){lblDisplay.Text = "";}lblDisplay.Text += key;break;}}float _minNum = 0;[Browsable(true), Category("自定义属性"), Description("最小值")]public float MinNum{get{return _minNum;}set{if (_minNum > MaxNum){_minNum = MaxNum;}else{_minNum = value;}lblMinNum.Text = _minNum.ToString();this.Invalidate();}}float _maxNum = 1000;[Browsable(true), Category("自定义属性"), Description("最小值")]public float MaxNum{get{return _maxNum;}set{if (_maxNum < MinNum){_maxNum = MinNum;}else{_maxNum = value;}lblMaxNum.Text = _maxNum.ToString();this.Invalidate();}}/// <summary>/// 为指定控件添加数字键盘/// </summary>/// <param name="targetControlNames">需要添加数字键盘的控件名集合</param>public void RegisterNumberKeyBoard(string[] targetControlNames){if (targetControlNames != null && targetControlNames.Length != 0){GetControlByControlName(this.TopLevelControl, targetControlNames);}foreach (var item in targetControls){if (item is TextBox){//给该控件注册获取光标事件(item as TextBox).GotFocus += TargetControl_GotFocus;}}}/// <summary>///根据目标控件名获取控件集合/// </summary>/// <param name="control"></param>void GetControlByControlName(Control control, string[] targetNames){if (targetNames.FirstOrDefault(item => item.Equals(control.Name)) != null){targetControls.Add(control);}if (control.HasChildren){foreach (Control c in control.Controls){GetControlByControlName(c, targetNames);}}}}public class NumKeyBoardEventArgs : EventArgs{public NumKeyBoardEventArgs(Control targetControl, float val){this.TargetControl = targetControl;this.Value = val;}/// <summary>/// 目标控件/// </summary>public Control TargetControl { get; private set; }/// <summary>/// 数字键盘输入的值/// </summary>public float Value { get; private set; }}

5,使用Graphics绘制LED。

效果:

LED控件代码:
  public partial class LED : UserControl{public LED(){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);}float outEllipseWidth = 5;[Browsable(true), Category("自定义属性"), Description("外圆的宽度")]public float OutEllipseWidth{get{return outEllipseWidth;}set{if (value < 0){outEllipseWidth = 2;}else{outEllipseWidth = value;}this.Invalidate();}}Color outEllipseColor = Color.Lime;[Browsable(true), Category("自定义属性"), Description("外圆的颜色")]public Color OutEllipseColor{get{return outEllipseColor;}set{outEllipseColor = value;this.Invalidate();}}float outGapWidth = 3;[Browsable(true), Category("自定义属性"), Description("外间隙宽度")]public float OutCapWidth{get{return outGapWidth;}set{if (value < 0){outGapWidth = 2;}else{outGapWidth = value;}this.Invalidate();}}Color centerEllipseColor = Color.Lime;[Browsable(true), Category("自定义属性"), Description("中心圆的颜色")]public Color CenterEllipseColor{get{return centerEllipseColor;}set{centerEllipseColor = value;this.Invalidate();}}protected override void OnPaint(PaintEventArgs e){base.OnPaint(e);Graphics g = e.Graphics;g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;//绘制外圆g.DrawEllipse(new Pen(OutEllipseColor, OutEllipseWidth), OutEllipseWidth, OutEllipseWidth, Width - OutEllipseWidth * 2, Height - OutEllipseWidth * 2);//绘制内圆PointF p = new PointF((float)(1.5 * OutEllipseWidth) + OutCapWidth, (float)(1.5 * OutEllipseWidth) + OutCapWidth);float centerWidth = Width - (float)(2 * (1.5 * OutEllipseWidth + OutCapWidth));float centerHeight = Height - (float)(2 * (1.5 * OutEllipseWidth + OutCapWidth));RectangleF centerRec = new RectangleF(p,new SizeF(centerWidth,centerHeight));g.FillEllipse(new SolidBrush(CenterEllipseColor), centerRec);}}

6,使用Graphics绘制流动条。

效果:

F

FlowControl代码 :
 public partial class FlowControl : UserControl{private float startOffset = 0.0f;private Timer mytimer = new Timer();Graphics g;public FlowControl(){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);mytimer.Interval = 50;mytimer.Tick += Mytimer_Tick;mytimer.Start();}private void Mytimer_Tick(object sender, EventArgs e){startOffset += moveSpeed;if (Math.Abs(startOffset) > BarLength + GapLength){startOffset = 0;}this.Invalidate();}#region Filedsprivate int barHeight = 5;[Browsable(true), Category("自定义属性"), Description("流动条宽度")]public int BarHeight{get { return barHeight; }set{this.barHeight = value;base.Invalidate();}}private Color barColor = Color.DodgerBlue;[Browsable(true), Category("自定义属性"), Description("获取或设置管道控件的流动块颜色")]public Color BarColor{get{return this.barColor;}set{this.barColor = value;base.Invalidate();}}private Color borderColor = Color.DimGray;[Browsable(true), Category("自定义属性"), Description("获取或设置管道边线颜色")]public Color BorderColor{get{return this.borderColor;}set{this.borderColor = value;base.Invalidate();}}private float borderWidth = 1;[Browsable(true), Category("自定义属性"), Description("获取或设置管道壁厚度")]public float BorderWidth{get{return this.borderWidth;}set{this.borderWidth = value;base.Invalidate();}}private Color pipeEdgeColor = Color.DimGray;[Browsable(true), Category("自定义属性"), Description("获取或设置管道边缘颜色")]public Color PipeEdgeColor{get{return this.pipeEdgeColor;}set{this.pipeEdgeColor = value;base.Invalidate();}}private Color pipeCenterColor = Color.LightGray;[Browsable(true), Category("自定义属性"), Description("获取或设置管道控件的中心颜色")]public Color PipeCenterColor{get{return this.pipeCenterColor;}set{this.pipeCenterColor = value;base.Invalidate();}}private PipeTurnDirection pipeTurnLeft = PipeTurnDirection.None;[Browsable(true), Category("自定义属性"), Description("左管道的转向类型")]public PipeTurnDirection PipeTurnLeft{get{return this.pipeTurnLeft;}set{this.pipeTurnLeft = value;base.Invalidate();}}private PipeTurnDirection pipeTurnRight = PipeTurnDirection.None;[Browsable(true), Category("自定义属性"), Description("右管道的转向类型")]public PipeTurnDirection PipeTurnRight{get{return this.pipeTurnRight;}set{this.pipeTurnRight = value;base.Invalidate();}}private DirectionStyle pipeLineDirection = DirectionStyle.Horizontal;[Browsable(true), Category("自定义属性"), Description("设置管道是横向的还是纵向的")]public DirectionStyle PipeLineDirection{get{return this.pipeLineDirection;}set{this.pipeLineDirection = value;int temp;if (value == DirectionStyle.Horizontal){temp = Height;Height = Width;Width = temp;}else{temp = Width;Width = Height;Height = temp;}base.Invalidate();}}private bool isActive = false;[Browsable(true), Category("自定义属性"), DefaultValue(false), Description("获取或设置管道线是否激活液体显示")]public bool IsActive{get{return this.isActive;}set{this.isActive = value;this.mytimer.Enabled = value;base.Invalidate();}}private float moveSpeed = 0.3f;[Browsable(true), Category("自定义属性"), Description("管道线液体流动的速度,0为静止,正数为正向流动,负数为反向流动")]public float MoveSpeed{get{return this.moveSpeed;}set{this.moveSpeed = value;base.Invalidate();}}private int barLength = 5;[Browsable(true), Category("自定义属性"), Description("流动条长度")]public int BarLength{get{return this.barLength;}set{this.barLength = value;base.Invalidate();}}private int gapLength = 5;[Browsable(true), Category("自定义属性"), Description("间隙长度")]public int GapLength{get{return this.gapLength;}set{this.gapLength = value;base.Invalidate();}}#endregionprotected override void OnResize(EventArgs e){if (PipeLineDirection == DirectionStyle.Horizontal){if (Width < 2 * Height){Width = 2 * Height;}}else{if (Height < 2 * Width){Height = 2 * Width;}}base.OnResize(e);}protected override void OnPaint(PaintEventArgs e){//  base.OnPaint(e);g = e.Graphics;Rectangle rec;Rectangle rec2;GraphicsPath graphicsPath = new GraphicsPath();if (PipeLineDirection == DirectionStyle.Horizontal){#region 水平switch (pipeTurnLeft){case PipeTurnDirection.Up:rec = new Rectangle(0, -Height, 2 * Height, 2 * Height);rec2 = new Rectangle(rec.X + (int)BorderWidth / 2, rec.Y, rec.Width - (int)BorderWidth, rec.Height - (int)BorderWidth / 2);PaintElliple(g, rec, rec2, 90, 90);// path.AddArc(new Rectangle( Height / 2, rec.Y /2, Height , Height), 90, 90);//特别需要注意角度旋转方向,如果角度旋转方向选错就形成闭环graphicsPath.AddArc(new Rectangle(this.Height / 2, this.Height / 2 * (-1) - 1, this.Height, this.Height), 180.0f, -90.0f);break;case PipeTurnDirection.Down:rec = new Rectangle(0, 0, 2 * Height, 2 * Height);rec2 = new Rectangle(rec.X + (int)BorderWidth / 2, rec.Y + (int)BorderWidth / 2, rec.Width - (int)BorderWidth, rec.Height - (int)BorderWidth / 2);PaintElliple(g, rec, rec2, 180, 90);graphicsPath.AddArc(new Rectangle(Height / 2, Height / 2, Height, Height), 180, 90);break;case PipeTurnDirection.Left:case PipeTurnDirection.Right:case PipeTurnDirection.None:PointF[] points = new PointF[] { new PointF(Height, BorderWidth / 2), new PointF(0, BorderWidth / 2), new PointF(0, Height - BorderWidth / 2), new PointF(Height, Height - BorderWidth / 2) };PaintRectangle(g, new Rectangle(0, 0, Height, Height), points);graphicsPath.AddLine(new PointF(0, Height / 2), new PointF(Height, Height / 2));break;default:break;}switch (PipeTurnRight){case PipeTurnDirection.Up:rec = new Rectangle(Width - 2 * Height, -Height, 2 * Height, 2 * Height);rec2 = new Rectangle(rec.X + (int)BorderWidth / 2, rec.Y, rec.Width - (int)BorderWidth, rec.Height - (int)BorderWidth / 2);PaintElliple(g, rec, rec2, 0, 90);graphicsPath.AddArc(new Rectangle(rec.X + Height / 2, rec.Y / 2, Height, Height), 90, -90);break;case PipeTurnDirection.Down:rec = new Rectangle(Width - 2 * Height, 0, 2 * Height, 2 * Height);rec2 = new Rectangle(rec.X, rec.Y + (int)BorderWidth / 2, rec.Width - (int)BorderWidth / 2, rec.Height - (int)BorderWidth / 2);PaintElliple(g, rec, rec2, 270, 90);//特别需要注意角度旋转方向,如果角度旋转方向选错就形成闭环graphicsPath.AddArc(new Rectangle(rec.X + Height / 2, Height / 2, Height, Height), 270, 90);break;case PipeTurnDirection.Left:case PipeTurnDirection.Right:case PipeTurnDirection.None:PointF[] points = new PointF[] { new PointF(Width - Height, BorderWidth / 2), new PointF(Width, BorderWidth / 2), new PointF(Width, Height - BorderWidth / 2), new PointF(Width - Height, Height - BorderWidth / 2) };PaintRectangle(g, new Rectangle(Width - Height, 0, Height, Height), points);graphicsPath.AddLine(Width - Height, Height / 2, Width, Height / 2);break;default:break;}if (Width > Height * 2){PointF[] points = new PointF[] { new PointF(Height, BorderWidth / 2), new PointF(Width - Height, BorderWidth / 2), new PointF(Height, Height - BorderWidth / 2), new PointF(Width - Height, Height - BorderWidth / 2) };PaintRectangle(g, new Rectangle(Height, 0, Width - 2 * Height, Height), points);//  graphicsPath.AddLine(Height, Height / 2,Width- Height , Height / 2);}#endregion}else{//垂直switch (pipeTurnLeft){case PipeTurnDirection.Left:rec = new Rectangle(-Width, 0, 2 * Width, 2 * Width);rec2 = new Rectangle(rec.X, rec.Y + (int)BorderWidth / 2, rec.Width - (int)BorderWidth / 2, rec.Height - (int)BorderWidth);PaintElliple(g, rec, rec2, 270, 90);// path.AddArc(new Rectangle( Height / 2, rec.Y /2, Height , Height), 90, 90);//特别需要注意角度旋转方向,如果角度旋转方向选错就形成闭环graphicsPath.AddArc(new Rectangle(-this.Width / 2, this.Width / 2, this.Width, this.Width), 270.0f, 90.0f);break;case PipeTurnDirection.Right:rec = new Rectangle(0, 0, 2 * Width, 2 * Width);rec2 = new Rectangle(rec.X + (int)BorderWidth / 2, rec.Y + (int)BorderWidth / 2, rec.Width - (int)BorderWidth, rec.Height - (int)BorderWidth / 2);PaintElliple(g, rec, rec2, 180, 90);graphicsPath.AddArc(new Rectangle(Width / 2, Width / 2, Width, Width), 270, -90);break;case PipeTurnDirection.Up:case PipeTurnDirection.Down:case PipeTurnDirection.None:PointF[] points = new PointF[] { new PointF(BorderWidth / 2, 0), new PointF(BorderWidth / 2, Width), new PointF(Width - BorderWidth / 2, 0), new PointF(Width - BorderWidth / 2, Width) };PaintRectangle(g, new Rectangle(0, 0, Width, Width), points, LinearGradientMode.Horizontal);graphicsPath.AddLine(new PointF(Width / 2, 0), new PointF(Width / 2, Width));break;default:break;}switch (PipeTurnRight){case PipeTurnDirection.Left:rec = new Rectangle(-Width, Height - 2 * Width, 2 * Width, 2 * Width);rec2 = new Rectangle(rec.X, rec.Y + (int)BorderWidth / 2, rec.Width - (int)BorderWidth / 2, rec.Height - (int)BorderWidth);PaintElliple(g, rec, rec2, 0, 90);//特别需要注意角度旋转方向,如果角度旋转方向选错就形成闭环graphicsPath.AddArc(new Rectangle(rec.X / 2, rec.Y + Width / 2, this.Width, this.Width), 0f, 90.0f);break;case PipeTurnDirection.Right:rec = new Rectangle(0, Height - 2 * Width, 2 * Width, 2 * Width);rec2 = new Rectangle(rec.X + (int)BorderWidth / 2, rec.Y + 1, rec.Width - (int)BorderWidth, rec.Height - (int)BorderWidth / 2);PaintElliple(g, rec, rec2, 90, 90);graphicsPath.AddArc(new Rectangle(Width / 2, rec.Y + Width / 2, Width, Width), 180, -90);break;case PipeTurnDirection.Up:case PipeTurnDirection.Down:case PipeTurnDirection.None:PointF[] points = new PointF[] { new PointF(BorderWidth / 2, Height - Width), new PointF(BorderWidth / 2, Height), new PointF(Width - BorderWidth / 2, Height - Width), new PointF(Width - BorderWidth / 2, Height) };PaintRectangle(g, new Rectangle(0, Height - Width, Width, Width), points, LinearGradientMode.Horizontal);graphicsPath.AddLine(new PointF(Width / 2, Height - Width), new PointF(Width / 2, Height));break;default:break;}if (Height > Width * 2){PointF[] points = new PointF[] { new PointF(BorderWidth / 2, Width), new PointF(BorderWidth / 2, Height - Width), new PointF(Width - BorderWidth / 2, Width), new PointF(Width - BorderWidth / 2, Height - Width) };PaintRectangle(g, new Rectangle(0, Width, Width, Height - 2 * Width), points, LinearGradientMode.Horizontal);// graphicsPath.AddLine(Height, Height / 2,Width- Height , Height / 2);}}if (IsActive){//绘制流动条Pen barPen = new Pen(BarColor, BarHeight);barPen.DashStyle = DashStyle.Custom;barPen.DashOffset = startOffset;barPen.DashPattern = new float[] { BarLength, GapLength };graphicsPath.StartFigure();g.DrawPath(barPen, graphicsPath);}}//绘制椭圆与圆弧void PaintElliple(Graphics g, Rectangle rec, Rectangle recArc, float startAngle, float sweepAngle){GraphicsPath graphicsPath = new GraphicsPath();graphicsPath.AddEllipse(rec);//画刷效果呈现由中心向四方层叠     PathGradientBrush brush = new PathGradientBrush(graphicsPath);brush.CenterPoint = new PointF(rec.X + rec.Width / 2, rec.Y + rec.Height / 2);brush.InterpolationColors = new ColorBlend() { Colors = new Color[] { PipeEdgeColor, PipeCenterColor, PipeEdgeColor }, Positions = new float[] { 0, 0.5f, 1 } };g.FillPie(brush, rec, startAngle, sweepAngle);g.DrawArc(new Pen(BorderColor, BorderWidth), recArc, startAngle, sweepAngle);}void PaintRectangle(Graphics g, Rectangle rec, PointF[] points, LinearGradientMode linearGradientMode = LinearGradientMode.Vertical){//画刷效果呈现线型分布,注意与PathGradientBrush的区别LinearGradientBrush brush = new LinearGradientBrush(rec, PipeEdgeColor, PipeCenterColor, linearGradientMode);brush.InterpolationColors = new ColorBlend() { Colors = new Color[] { PipeEdgeColor, PipeCenterColor, PipeEdgeColor }, Positions = new float[] { 0, 0.5f, 1 } };brush.InterpolationColors = new ColorBlend() { Colors = new Color[] { PipeEdgeColor, PipeCenterColor, PipeEdgeColor }, Positions = new float[] { 0, 0.5f, 1 } };g.FillRectangle(brush, rec);g.DrawLine(new Pen(BorderColor, BorderWidth), points[0], points[1]);g.DrawLine(new Pen(BorderColor, BorderWidth), points[2], points[3]);}}/// <summary>/// 管道左、右的转向类型/// </summary>public enum PipeTurnDirection{Up = 1,Down,Left,Right,None}/// <summary>/// 管道的样式,水平还是数值/// </summary>public enum DirectionStyle{Horizontal = 1,Vertical}

7,使用Graphics绘制仪表盘1:

效果:

DashBoard控件代码
 [DefaultEvent("Click")]//指定默认事件public partial class DashBoard : UserControl{public DashBoard(){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);}Font _wordFont = new Font("微软雅黑", 10, FontStyle.Bold);[Browsable(true), Category("自定义属性"), Description("文字字体")]public Font WordFont{get{return _wordFont;}set{_wordFont = value;this.Invalidate();}}Color _wordColor = Color.Black;/// <summary>/// 文字颜色/// </summary>[Browsable(true), Category("自定义属性"), Description("文字颜色")]public Color WordColor{get{return _wordColor;}set{_wordColor = value;this.Invalidate();}}bool _isWordShow = true;/// <summary>/// 文字是否显示/// </summary>[Browsable(true), Category("自定义属性"), Description("文字是否显示")]public bool IsWordShow{get{return _isWordShow;}set{_isWordShow = value;this.Invalidate();}}string _wordFormat = "实际温度:{0}℃";/// <summary>/// 文字是否显示的格式,例如:"实际温度:{0}℃",{0}为实际值的占位符/// </summary>[Browsable(true), Category("自定义属性"), Description("文字是否显示的格式,例如:'实际温度:{0}℃',{0}为实际值的占位符")]public string WordFormat{get{return _wordFormat;}set{_wordFormat = value;this.Invalidate();}}float _wordPositionFactor = 0.6f;/// <summary>/// 底部文字所在位置/// </summary>[Browsable(true), Category("自定义属性"), Description("底部文字所在位置")]public float WordPositionFactor{get{return _wordPositionFactor;}set{if (value < 0 || value > 1){_wordPositionFactor = 0.6f;}else{_wordPositionFactor = value;}this.Invalidate();}}float _startValue = 0;/// <summary>/// 开始值/// </summary>[Browsable(true), Category("自定义属性"), Description("开始值")]public float StartValue{get{return _startValue;}set{_startValue = value;this.Invalidate();}}float _endValue = 160;/// <summary>/// 结束值/// </summary>[Browsable(true), Category("自定义属性"), Description("结束值")]public float EndValue{get{return _endValue;}set{_endValue = value;this.Invalidate();}}float _sweepRange = 240;/// <summary>/// 量程跨度,即从开始值到结束值所占用的角度/// </summary>[Browsable(true), Category("自定义属性"), Description("量程跨度,即从开始值到结束值所占用的角度")]public float SweepRange{get{return _sweepRange;}set{if (value < 0){_sweepRange = 240;}else{_sweepRange = value;}this.Invalidate();}}int _largeMarkCount = 9;/// <summary>/// 刻度间隔值/// </summary>[Browsable(true), Category("自定义属性"), Description("刻度间隔值")]public int LargeMarkCount{get{return _largeMarkCount;}set{if (value < 0){_largeMarkCount = 9;}else{_largeMarkCount = value;}this.Invalidate();}}MarkType _markStyle = MarkType.Average;/// <summary>/// 刻度分配样式,是平均分配还是自定义刻度值分配/// </summary>[Browsable(true), Category("自定义属性"), Description(" 刻度分配样式,是平均分配还是自定义刻度值分配")]public MarkType MarkStyle{get{return _markStyle;}set{_largeMarkCount = 9;_markStyle = value;this.Invalidate();}}float[] _customMarkValue = { 0, 20, 40, 60, 80, 100, 120, 140, 160 };/// <summary>/// 自定义刻度值/// </summary>[Browsable(true), Category("自定义属性"), Description("自定义刻度值")]public float[] CustomMarkValue{get{return _customMarkValue;}set{_customMarkValue = value;this.Invalidate();}}Color _firstColor = Color.DodgerBlue;/// <summary>/// 第一部分颜色/// </summary>[Browsable(true), Category("自定义属性"), Description("第一部分颜色")]public Color FirstColor{get{return _firstColor;}set{_firstColor = value;this.Invalidate();}}int _firstColorHaveMarkCount = 6;/// <summary>/// 第一部分颜色所拥有的刻度数量/// </summary>[Browsable(true), Category("自定义属性"), Description("第一部分颜色所拥有的刻度数量")]public int FirstColorHaveMarkCount{get{return _firstColorHaveMarkCount;}set{if (value < 0){_firstColorHaveMarkCount = 2;}else{_firstColorHaveMarkCount = value;}this.Invalidate();}}Color _secondColor = Color.LightGray;/// <summary>/// 第2部分颜色/// </summary>[Browsable(true), Category("自定义属性"), Description("第2部分颜色")]public Color SecondColor{get{return _secondColor;}set{_secondColor = value;this.Invalidate();}}int _outCircleWidth = 3;/// <summary>/// 外圆宽度/// </summary>[Browsable(true), Category("自定义属性"), Description("外圆宽度")]public int OutCircleWidth{get{return _outCircleWidth;}set{if (value < 0){return;}else{_outCircleWidth = value;}this.Invalidate();}}float _pointerPartFactor = 0.1f;/// <summary>/// 指针部分所占的比例/// </summary>[Browsable(true), Category("自定义属性"), Description("指针部分所占的比例")]public float PointerPartFactor{get{return _pointerPartFactor;}set{if (value < 0 || value > 1){_pointerPartFactor = 0.2f;}else{_pointerPartFactor = value;}this.Invalidate();}}/// <summary>/// 尺寸/// </summary>int Dimensions{get{if (Width < Height){return Width;}return Height;}}int _outCap = 5;/// <summary>/// 外间隙/// </summary>[Browsable(true), Category("自定义属性"), Description("外间隙")]public int OutGap{get{return _outCap;}set{if (value < 0){return;}_outCap = value;this.Invalidate();}}int _innerCap = 15;/// <summary>/// 内间隙/// </summary>[Browsable(true), Category("自定义属性"), Description("内间隙")]public int InnerGap{get{return _innerCap;}set{if (value < 0){return;}_innerCap = value;this.Invalidate();}}float _actualValue = 60;/// <summary>/// 实际值/// </summary>[Browsable(true), Category("自定义属性"), Description("实际值")]public float ActualValue{get{return _actualValue;}set{_actualValue = value;this.Invalidate();}}Color _markWordColor = Color.Black;[Browsable(true), Category("自定义属性"), Description("刻度文字颜色")]public Color MarkWordColor{get{return _markWordColor;}set{_markWordColor = value;}}Font _markWordFont = DefaultFont;[Browsable(true), Category("自定义属性"), Description("刻度文字字体")]public Font MarkWordFont{get{return _markWordFont;}set{_markWordFont = value;this.Invalidate();}}protected override void OnPaint(PaintEventArgs e){base.OnPaint(e);Graphics g = e.Graphics;//计算需要绘制的刻度数量g.SmoothingMode = SmoothingMode.AntiAlias; //使绘图质量最高,即消除锯齿g.InterpolationMode = InterpolationMode.HighQualityBicubic;g.CompositingQuality = CompositingQuality.HighQuality;Dictionary<int, float> dic = new Dictionary<int, float>();if (MarkStyle == MarkType.Average){for (int i = 0; i < LargeMarkCount; i++){dic.Add(i, i * (SweepRange / (LargeMarkCount - 1)));}}else{for (int i = 0; i < CustomMarkValue.Length; i++){dic.Add(i, (CustomMarkValue[i] - CustomMarkValue.Min()) / Math.Abs((CustomMarkValue.Max() - CustomMarkValue.Min())) * SweepRange);}}//绘制外圆if (FirstColorHaveMarkCount > dic.Count){FirstColorHaveMarkCount = dic.Count;}float startAngle = (360 - SweepRange) / 2 + 90;//第1段g.DrawArc(new Pen(FirstColor, OutCircleWidth), OutGap, OutGap, Dimensions - OutGap * 2, Dimensions - OutGap * 2, startAngle, dic[FirstColorHaveMarkCount - 1]);//第2段g.DrawArc(new Pen(SecondColor, OutCircleWidth), OutGap, OutGap, Dimensions - OutGap * 2, Dimensions - OutGap * 2, dic[FirstColorHaveMarkCount - 1] + startAngle, dic[dic.Count - 1] - dic[FirstColorHaveMarkCount - 1]);//绘制刻度//偏移原点g.TranslateTransform(Dimensions / 2, Dimensions / 2);//旋转角度g.RotateTransform(-_sweepRange / 2);foreach (var key in dic.Keys){RectangleF rec = new RectangleF(-2, -(Dimensions - 2 * OutGap) / 2 - OutGap, 4, OutGap * 2);if (key != 0){g.RotateTransform(dic[key] - dic[key - 1]);}if (key < FirstColorHaveMarkCount){g.FillRectangle(new SolidBrush(FirstColor), rec);}else{g.FillRectangle(new SolidBrush(SecondColor), rec);}}//恢复坐标g.ResetTransform();//移动原点g.TranslateTransform(Dimensions / 2, Dimensions / 2);//旋转角度//  g.RotateTransform(-_sweepRange / 2);//绘制MarkWord//  PointF p = new PointF((float)(Dimensions * Math.Cos(230*1.0 / 180 * Math.PI)), (float)(Dimensions * Math.Sin(230*1.0 / 180 * Math.PI)));// g.DrawLine(Pens.Black, new PointF(0, 0), p);float largeInterval = SweepRange / (LargeMarkCount - 1);foreach (var key in dic.Keys){//绘制文字string markWord;if (MarkStyle == MarkType.Average){markWord = Math.Round(StartValue + key * (EndValue - StartValue) / (LargeMarkCount - 1), 1).ToString();}else{markWord = Math.Round(CustomMarkValue[key], 1).ToString();}float wordRadius = Dimensions / 2 - OutCircleWidth - OutGap - InnerGap;double x = wordRadius * Math.Cos((dic[key] + startAngle) / 180 * Math.PI);double y = wordRadius * Math.Sin((dic[key] + startAngle) / 180 * Math.PI);SizeF size = g.MeasureString(markWord, this.Font);PointF wordPoint = new PointF((float)x - size.Width / 2, (float)y - size.Height / 2);g.DrawString(markWord, MarkWordFont, new SolidBrush(MarkWordColor), wordPoint);}if (IsWordShow){//绘制底部文字string txt = string.Format(WordFormat, ActualValue);SizeF wordSize = g.MeasureString(txt, WordFont);PointF txtPoint = new PointF(-wordSize.Width / 2, Dimensions / 2 * WordPositionFactor);g.DrawString(txt, WordFont, new SolidBrush(WordColor), txtPoint);}//绘制指针//圆心半径float circleRadius = Dimensions / 2 * this.PointerPartFactor;float pointerLength = circleRadius * 6;float trackWidth = pointerLength / 4;//绘制指针圆心g.FillEllipse(new SolidBrush(FirstColor), -circleRadius, -circleRadius, 2 * circleRadius, 2 * circleRadius);float relativeAngle;if (ActualValue > EndValue){relativeAngle = SweepRange;}else if (ActualValue < StartValue){relativeAngle = 0;}else{if (MarkStyle == MarkType.Average){relativeAngle = ((ActualValue - StartValue) / (EndValue - StartValue)) * SweepRange;}else{if (CustomMarkValue.Length < 2){CustomMarkValue = new float[] { 0, 20, 30 };}relativeAngle = (ActualValue - CustomMarkValue.Min()) / (CustomMarkValue.Max() - CustomMarkValue.Min()) * SweepRange;}}//绘制轨迹g.DrawArc(new Pen(FirstColor, trackWidth), -pointerLength + trackWidth / 2, -pointerLength + trackWidth / 2, 2 * pointerLength - trackWidth, 2 * pointerLength - trackWidth, startAngle, relativeAngle);//旋转角度g.RotateTransform(-_sweepRange / 2);//当前值对应的相对角度//绘制指针g.RotateTransform(relativeAngle);g.DrawLine(new Pen(FirstColor, 2), -1, 0, -1, -pointerLength);}}public enum MarkType{/// <summary>/// 平均分配刻度/// </summary>Average,/// <summary>/// 自定义刻度值分配/// </summary>Custom}
}

8,使用Graphics绘制仪表盘2:

效果:

Gague控件代码:
 [DefaultEvent("Click")]public partial class Gague : UserControl{public Gague(){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);}Font _wordFont = new Font("微软雅黑", 10, FontStyle.Bold);[Browsable(true), Category("自定义属性"), Description("文字字体")]public Font WordFont{get{return _wordFont;}set{_wordFont = value;this.Invalidate();}}Color _wordColor = Color.SeaGreen;/// <summary>/// 文字颜色/// </summary>[Browsable(true), Category("自定义属性"), Description("文字颜色")]public Color WordColor{get{return _wordColor;}set{_wordColor = value;this.Invalidate();}}bool _isWordShow = true;/// <summary>/// 文字是否显示/// </summary>[Browsable(true), Category("自定义属性"), Description("文字是否显示")]public bool IsWordShow{get{return _isWordShow;}set{_isWordShow = value;this.Invalidate();}}string _wordFormat = "实际温度:{0}℃";/// <summary>/// 文字是否显示的格式,例如:"实际温度:{0}℃",{0}为实际值的占位符/// </summary>[Browsable(true), Category("自定义属性"), Description("文字是否显示的格式,例如:'实际温度:{0}℃',{0}为实际值的占位符")]public string WordFormat{get{return _wordFormat;}set{_wordFormat = value;this.Invalidate();}}float _wordPositionFactor = 0.7f;/// <summary>/// 底部文字所在位置/// </summary>[Browsable(true), Category("自定义属性"), Description("底部文字所在位置")]public float WordPositionFactor{get{return _wordPositionFactor;}set{if (value < 0 || value > 1){_wordPositionFactor = 0.6f;}else{_wordPositionFactor = value;}this.Invalidate();}}float _startValue = 0;/// <summary>/// 开始值/// </summary>[Browsable(true), Category("自定义属性"), Description("开始值")]public float StartValue{get{return _startValue;}set{_startValue = value;this.Invalidate();}}float _endValue = 160;/// <summary>/// 结束值/// </summary>[Browsable(true), Category("自定义属性"), Description("结束值")]public float EndValue{get{return _endValue;}set{_endValue = value;this.Invalidate();}}float _lowAlarmValue = 25;/// <summary>/// 低报警阈值/// </summary>[Browsable(true), Category("自定义属性"), Description("低警戒值")]public float LowAlarmValue{get{return _lowAlarmValue;}set{if (value < StartValue){_lowAlarmValue = StartValue;}else{_lowAlarmValue = value;}this.Invalidate();}}Color _lowAlarmColor = Color.Red;/// <summary>/// 低警区域颜色/// </summary>[Browsable(true), Category("自定义属性"), Description("低警区域颜色")]public Color LowAlarmColor{get{return _lowAlarmColor;}set{_lowAlarmColor = value;this.Invalidate();}}float _hightAlarmValue = 120;/// <summary>/// 高报警阈值/// </summary>[Browsable(true), Category("自定义属性"), Description("高警戒值")]public float HightAlarmValue{get{return _hightAlarmValue;}set{if (value > EndValue){_hightAlarmValue = EndValue;}else{_hightAlarmValue = value;}this.Invalidate();}}Color _hightAlarmColor = Color.Red;/// <summary>/// 高报警区域颜色/// </summary>[Browsable(true), Category("自定义属性"), Description("高警区域颜色")]public Color HightAlarmColor{get{return _hightAlarmColor;}set{_hightAlarmColor = value;this.Invalidate();}}float _sweepRange = 240;/// <summary>/// 量程跨度,即从开始值到结束值所占用的角度/// </summary>[Browsable(true), Category("自定义属性"), Description("量程跨度,即从开始值到结束值所占用的角度")]public float SweepRange{get{return _sweepRange;}set{if (value < 0){_sweepRange = 240;}else{_sweepRange = value;}this.Invalidate();}}Color _markColor = Color.LightSeaGreen;/// <summary>/// 刻度颜色/// </summary>[Browsable(true), Category("自定义属性"), Description("刻度颜色")]public Color MarkColor{get{return _markColor;}set{_markColor = value;this.Invalidate();}}Color _pointerColor = Color.Green;/// <summary>/// 指针颜色/// </summary>[Browsable(true), Category("自定义属性"), Description("指针颜色")]public Color PointerColor{get{return _pointerColor;}set{_pointerColor = value;this.Invalidate();}}float _pointerPartFactor = 0.8f;/// <summary>/// 指针部分所占的比例/// </summary>[Browsable(true), Category("自定义属性"), Description("指针部分所占的比例")]public float PointerPartFactor{get{return _pointerPartFactor;}set{if (value < 0 || value > 1){_pointerPartFactor = 0.2f;}else{_pointerPartFactor = value;}this.Invalidate();}}/// <summary>/// 尺寸/// </summary>int Dimensions{get{if (Width < Height){return Width;}return Height;}}int _outCap = 5;/// <summary>/// 外间隙/// </summary>[Browsable(true), Category("自定义属性"), Description("外间隙")]public int OutGap{get{return _outCap;}set{if (value < 0){return;}_outCap = value;this.Invalidate();}}int _innerCap = 3;/// <summary>/// 内间隙/// </summary>[Browsable(true), Category("自定义属性"), Description("内间隙")]public int InnerGap{get{return _innerCap;}set{if (value < 0){return;}_innerCap = value;this.Invalidate();}}float _actualValue = 60;/// <summary>/// 实际值/// </summary>[Browsable(true), Category("自定义属性"), Description("实际值")]public float ActualValue{get{return _actualValue;}set{_actualValue = value;this.Invalidate();}}Color _markWordColor = Color.Black;[Browsable(true), Category("自定义属性"), Description("刻度文字颜色")]public Color MarkWordColor{get{return _markWordColor;}set{_markWordColor = value;}}Font _markWordFont = DefaultFont;[Browsable(true), Category("自定义属性"), Description("刻度文字颜色")]public Font MarkWordFont{get{return _markWordFont;}set{_markWordFont = value;this.Invalidate();}}int _largeMarkCount = 9;[Browsable(true), Category("自定义属性"), Description("大刻度数量")]public int LargeMarkCount{get{return _largeMarkCount;}set{if (value < 0){_largeMarkCount = 5;}else{_largeMarkCount = value;}this.Invalidate();}}int _markWidth = 3;[Browsable(true), Category("自定义属性"), Description("刻度宽度")]public int MarkWidth{get{return _markWidth;}set{if (value < 0){_markWidth = 3;}else{_markWidth = value;}this.Invalidate();}}int _markHeight = 4;[Browsable(true), Category("自定义属性"), Description("刻度宽度")]public int MarkHeight{get{return _markHeight;}set{if (value < 0){_markHeight = 4;}else{_markHeight = value;}this.Invalidate();}}int _markWordGap = 24;[Browsable(true), Category("自定义属性"), Description("刻度文字与刻度间隙")]public int MarkWordGap{get{return _markWordGap;}set{if (value < 0){_markWordGap = 4;}else{_markWordGap = value;}this.Invalidate();}}protected override void OnPaint(PaintEventArgs e){base.OnPaint(e);Graphics g = e.Graphics;g.SmoothingMode = SmoothingMode.AntiAlias; //使绘图质量最高,即消除锯齿g.InterpolationMode = InterpolationMode.HighQualityBicubic;g.CompositingQuality = CompositingQuality.HighQuality;g.SmoothingMode = SmoothingMode.HighQuality;//绘制刻度//计算小刻度大小float smallMarkAngle = SweepRange / ((LargeMarkCount - 1) * 5);g.TranslateTransform(Dimensions / 2, Dimensions / 2);float offset = OutGap + InnerGap + MarkHeight;g.RotateTransform(-_sweepRange / 2);for (int i = 0; i <= LargeMarkCount - 1; i++){//绘制大刻度PointF[] points = new PointF[]{new PointF(-MarkWidth*1.0f/2, offset-Dimensions/2),new PointF(MarkWidth*1.0f/2,offset-Dimensions/2),new PointF(MarkWidth*1.0f/2,offset+MarkHeight*2-Dimensions/2),new PointF(0,offset+MarkHeight*2+  MarkWidth*1.0f/2-Dimensions/2),new PointF(-MarkWidth*1.0f/2,offset+MarkHeight*2-Dimensions/2)};g.FillPolygon(new SolidBrush(MarkColor), points);g.RotateTransform(smallMarkAngle);if (i != LargeMarkCount - 1){//绘制小刻度for (int j = 0; j < 4; j++){g.FillRectangle(new SolidBrush(MarkColor), -MarkWidth * 1.0f / 2, offset - Dimensions / 2, MarkWidth, MarkHeight);g.RotateTransform(smallMarkAngle);}}}//初始化原点,并将原点置于圆心g.ResetTransform();g.TranslateTransform(Dimensions / 2, Dimensions / 2);float startAngle = 180 - SweepRange / 2 + 90;float lowAlarmAngle;if (LowAlarmValue == StartValue){lowAlarmAngle = 0;}else{lowAlarmAngle = (LowAlarmValue - StartValue) * 1.0f / (EndValue - StartValue) * SweepRange;}float hightAlarmAngle;if (HightAlarmValue == EndValue){hightAlarmAngle = 0;}else{hightAlarmAngle = (EndValue - HightAlarmValue) * 1.0f / (EndValue - StartValue) * SweepRange;}//绘制警戒线Pen lowAlarmPen = new Pen(LowAlarmColor, MarkWidth){DashStyle = DashStyle.Dash,DashPattern = new float[] { 3, 1 }};Pen hightAlarmPen = new Pen(HightAlarmColor, MarkWidth){DashStyle = DashStyle.Dash,DashPattern = new float[] { 3, 1 }};g.DrawArc(lowAlarmPen, OutGap - Dimensions / 2, OutGap - Dimensions / 2, Dimensions - 2 * OutGap, Dimensions - 2 * OutGap, startAngle, lowAlarmAngle);g.DrawArc(hightAlarmPen, OutGap - Dimensions / 2, OutGap - Dimensions / 2, Dimensions - 2 * OutGap, Dimensions - 2 * OutGap, startAngle + SweepRange - hightAlarmAngle, hightAlarmAngle);//绘制刻度文字float largeMarkInterval = (EndValue - StartValue) / (LargeMarkCount - 1);for (int i = 0; i <= LargeMarkCount - 1; i++){float angle = startAngle + i * 5 * smallMarkAngle;float radius = Dimensions / 2 - (OutGap + MarkWidth + InnerGap + MarkWordGap);PointF p = new PointF(radius * (float)(Math.Cos(angle / 180 * Math.PI)), radius * (float)(Math.Sin(angle / 180 * Math.PI)));string wordtxt = (Math.Round(StartValue + i * largeMarkInterval, 1)).ToString();SizeF wordSize = g.MeasureString(wordtxt, MarkWordFont);PointF wordPoint = new PointF(p.X - wordSize.Width / 2, p.Y - wordSize.Height / 2);g.DrawString(wordtxt, MarkWordFont, new SolidBrush(MarkWordColor), wordPoint);//  g.DrawLine(Pens.Black, new Point(0, 0), p);}//绘制文字if (this.IsWordShow){string word = string.Format(WordFormat, ActualValue);SizeF wSize = g.MeasureString(word, WordFont);float wordPosition = Dimensions / 2 * this.WordPositionFactor;PointF wPoint = new PointF(-wSize.Width / 2, wordPosition - wSize.Height / 2);g.DrawString(word, WordFont, new SolidBrush(WordColor), wPoint);}//绘制指针//使指针置于0位g.RotateTransform(-SweepRange / 2);//计算旋转的角度if (StartValue != EndValue){float pointerAngle;if (ActualValue < StartValue){pointerAngle = 0;}else if (ActualValue > EndValue){pointerAngle = SweepRange;}else{pointerAngle = (ActualValue - StartValue) / (EndValue - StartValue) * SweepRange;}g.RotateTransform(pointerAngle);}float pointerLenght = Dimensions / 2 * PointerPartFactor;float centerRadius = pointerLenght / 30;GraphicsPath path = new GraphicsPath();path.AddArc(-centerRadius, -centerRadius, 2 * centerRadius, 2 * centerRadius, 0, 180);path.AddLine(-centerRadius, 0, 0, -pointerLenght);g.FillPath(new SolidBrush(PointerColor), path);}}

相关文章:

C#绘制常用工业控件(仪表盘,流动条,开关等)

目录 1&#xff0c;使用Graphics绘制Toggle。 效果&#xff1a; 测试代码&#xff1a; Toggle控件代码&#xff1a; 2&#xff0c;使用Graphics绘制Switch。 效果&#xff1a; 测试代码&#xff1a; Switch控件代码&#xff1a; 3&#xff0c;使用Graphics绘制PanelHe…...

Ps:颜色模型、色彩空间及配置文件

颜色模型、色彩空间和配置文件是处理颜色的核心概念。它们虽然互相关联&#xff0c;但各自有不同的功能和作用。 通过理解这些概念及其关系&#xff0c;Photoshop 用户可以更好地管理和优化图像处理流程&#xff0c;确保颜色在不同设备和应用中的一致性和准确性。 颜色模型 Col…...

llvm后端之td定义指令信息

llvm后端之td定义指令信息 引言1 定义指令2 定义Operand3 定义SDNode4 PatFrags4.1 ImmLeaf4.2 PatLeaf 5 ComplexPattern6 谓词条件7 理解dag 引言 llvm后端通过td定义指令信息&#xff0c;并通过dag匹配将IR节点转换为平台相关的指令。 1 定义指令 td通过class Instructio…...

战地机房集装箱数据中心可视化:实时监控与管理

通过图扑可视化技术实时监控战地机房集装箱数据中心的各项运行指标和环境参数&#xff0c;提高部署效率和设备管理能力&#xff0c;确保数据中心稳定运行。...

Linux入门攻坚——31、rpc概念及nfs和samba

NFS&#xff1a;Network File System 传统意义上&#xff0c;文件系统在内核中实现 RPC&#xff1a;函数调用&#xff08;远程主机上的函数&#xff09;&#xff0c;Remote Procedure Call protocol 一部分功能由本地程序完成 另一部分功能由远程主机上的 NFS本质…...

内网穿透的应用-本地化部署Elasticsearch平替工具OpenObserve并实现无公网IP远程分析数据

文章目录 前言1. 安装Docker2. Docker镜像源添加方法3. 创建并启动OpenObserve容器4. 本地访问测试5. 公网访问本地部署的OpenObserve5.1 内网穿透工具安装5.2 创建公网地址 6. 配置固定公网地址 前言 本文主要介绍如何在Linux系统使用Docker快速本地化部署OpenObserve云原生可…...

哈希表 and 算法

哈希表&#xff1a; 哈希表&#xff08;Hash table&#xff09;&#xff0c;也被称为散列表&#xff0c;是一种根据关键码值&#xff08;Key value&#xff09;而直接进行访问的数据结构。它通过把关键码值映射到表中一个位置来访问记录&#xff0c;以加快查找的速度。这个映射…...

Comsol 共用声固耦合边界与热粘性声学边界的亥姆霍兹腔体超材料板精准隔声设计

声子晶体可分为局域共振型声子晶体和布拉格散射型声子晶体, 由于布拉格声子晶体需要的结构尺寸往往很大, 不便于实际应用; 而基于局域共振型机理的声子晶体能够实现“小体积控制大波长”, 因而有更加广泛的应用, 其中利用Helmholtz共鸣腔是局域共振型机理的典型应用, 近年来, H…...

Linux系统本地化部署Dify并安装Ollama运行llava大语言模型详细教程

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

极光出席深圳国际人工智能展并荣获“最具投资价值人工智能奖”

9月8-10日&#xff0c;由深圳市工业和信息化局、深圳市发展和改革委员会、深圳市科技创新局、深圳市政务服务和数据管理局、深圳市中小企业服务局共同指导&#xff0c;深圳市人工智能行业协会主办的第五届深圳国际人工智能展正式开幕。作为中国领先的客户互动和营销科技服务商&…...

人工智能领域的性能指的是什么

目录 1. 准确性&#xff08;Accuracy&#xff09; 2. 精确率与召回率&#xff08;Precision & Recall&#xff09; 3. F1分数 4. 运行时间与延迟&#xff08;Latency&#xff09; 5. 吞吐量&#xff08;Throughput&#xff09; 6. 可扩展性&#xff08;Scalability&a…...

SQL进阶技巧:如何利用SQL解决趣味赛马问题?| 非等值关联匹配问题

目录 0 问题描述 1 数据准备 2 问题分析 方法一:先分后合思想 方法2:非等值关联匹配 3 小结 0 问题描述 有一张赛马记录表,如下所示: create table RacingResults ( trace_id char(3) not null,race_date date not null, race_nbr int not null,win_name char(30) n…...

Vue Echarts报错Initialize failed: invalid dom解决方法

此问题是图表初始化时 找不到dom&#xff0c;以下是解决方法 1、不要用created&#xff08;用mounted&#xff09;&#xff0c;created这时候还只是创建了实例&#xff0c;但模板还没挂载完成&#xff1b; created&#xff1a; 在模板渲染成 html 前调用&#xff0c;通常初始…...

MySQL—死锁

什么是死锁&#xff1f; 好比是两个事务都在等待对方释放锁&#xff0c;之后进行下一步操作&#xff0c;但是最后双方都没有释放资源&#xff0c;所以导致一直处于等待的状态。 但是服务器不会让死锁的状态一直持续&#xff0c;会关闭其中一个影响较小的事务&#xff08;右边的…...

CS5363|CS5263升级方案|DP转HDMI 4K60HZ芯片方案

CS5363是一种高度集成的单芯片&#xff0c;适用于多个细分市场和显示应用&#xff0c;如Typec扩展、手机/电脑投屏、扩展底座、投影仪等。 CS5363管脚分布情况如下&#xff1a; CS5363是一款高度集成的单芯片&#xff0c;适用于多个mGeneral 支持最高分辨率/定时4k60Hz 支持…...

Git Lab 项目迁移到gitee 并且包含提交记录

步骤 1: 准备工作 1.安装Git&#xff1a;确保你在本地计算机上安装了Git。如果尚未安装&#xff0c;可以从Git官网下载并安装。 2.创建Gitee账号&#xff1a;如果你还没有Gitee账号&#xff0c;请先注册一个&#xff0c;访问Gitee官网进行注册。 3.创建新的Gitee仓库&#xff1…...

如何用用智能码二维码zhinengma.cn做空调机房巡检

用智能码二维码做空调机房巡检 引言 空调机房是保障建筑物内环境舒适度的关键设施&#xff0c;其巡检工作对于确保空调系统的稳定运行至关重要。通过引入智能码二维码技术&#xff0c;可以大大提高空调机房巡检的效率和准确性。 一、二维码在空调机房巡检中的应用 1.1 巡检…...

如何与客户保持高度粘性?这个系统给您答案

客户粘性是企业成功的关键因素之一&#xff0c;企客宝企微版在打通获客、转化、运营全链路方面发挥着重要作用&#xff0c;实现客户粘性的提升。 前言 客户粘性是企业成功的关键因素之一。企业需要不断通过各种手段提升客户粘性&#xff0c;保持客户忠诚度和长期合作关系。企客…...

算法知识点————两个栈实现一个队列

思路&#xff1a;当队列入队的时候&#xff0c;将元素入栈&#xff08;instack&#xff09;&#xff0c;当队列出栈的时候&#xff0c;先判断栈&#xff08;outstack&#xff09;是否为空&#xff0c;如果为空&#xff0c;则将栈&#xff08;instack&#xff09;的元素全部放入…...

并行程序设计基础——并行I/O(1)

目录 一、概述 1、按照读写定位分类 2、按照同步机制分类 3、按照参加读写操作的进程的限制分类 二、并行文件管理的基本操作 1、MPI_FILE_OPNE 2、MPI_FILE_CLOSE 3、MPI_FILE_DELETE 4、MPI_FILE_SET_SIZE 5、MPI_FILE_PREALLOCATE 6、MPI_FILE_GET_SIZE 7、MPI_…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...