前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
官网:https://www.hzhcontrols.cn
GitHub:https://github.com/kwwwvagaa/NetWinformControl
如果觉得写的还行,请点个 star 支持一下吧
麻烦博客下方点个【推荐】,谢谢
NuGet
Install-Package HZH_Controls
目录
c#Winform自定义控件-目录_c#winform自定义控件-有图标的按钮-CSDN博客
用处及效果
准备工作
请先了解GDI+和三角函数
开始
添加一个类UCValve,继承UserControl
添加一个阀门显示样式枚举
1 /// <summary>
2 /// Enum ValveStyle
3 /// </summary>
4 public enum ValveStyle
5 {
6 /// <summary>
7 /// 横向,开关在上方
8 /// </summary>
9 Horizontal_Top,
10 /// <summary>
11 /// 横向,开关在下方
12 /// </summary>
13 Horizontal_Bottom,
14 /// <summary>
15 /// 纵向,开关在左侧
16 /// </summary>
17 Vertical_Left,
18 /// <summary>
19 /// 纵向,开关在右侧
20 /// </summary>
21 Vertical_Right,
22 }
添加一些属性
1 /// <summary>
2 /// The valve style
3 /// </summary>
4 private ValveStyle valveStyle = ValveStyle.Horizontal_Top;
5
6 /// <summary>
7 /// Gets or sets the valve style.
8 /// </summary>
9 /// <value>The valve style.</value>
10 [Description("阀门样式"), Category("自定义")]
11 public ValveStyle ValveStyle
12 {
13 get { return valveStyle; }
14 set
15 {
16 valveStyle = value;
17 Refresh();
18 }
19 }
20
21 /// <summary>
22 /// The valve color
23 /// </summary>
24 private Color valveColor = Color.FromArgb(255, 77, 59);
25
26 /// <summary>
27 /// Gets or sets the color of the valve.
28 /// </summary>
29 /// <value>The color of the valve.</value>
30 [Description("阀门颜色"), Category("自定义")]
31 public Color ValveColor
32 {
33 get { return valveColor; }
34 set
35 {
36 valveColor = value;
37 Refresh();
38 }
39 }
40
41 /// <summary>
42 /// The switch color
43 /// </summary>
44 private Color switchColor = Color.FromArgb(232, 30, 99);
45
46 /// <summary>
47 /// Gets or sets the color of the switch.
48 /// </summary>
49 /// <value>The color of the switch.</value>
50 [Description("开关把手颜色"), Category("自定义")]
51 public Color SwitchColor
52 {
53 get { return switchColor; }
54 set
55 {
56 switchColor = value;
57 Refresh();
58 }
59 }
60
61 /// <summary>
62 /// The axis color
63 /// </summary>
64 private Color axisColor = Color.FromArgb(3, 169, 243);
65
66 /// <summary>
67 /// Gets or sets the color of the axis.
68 /// </summary>
69 /// <value>The color of the axis.</value>
70 [Description("轴颜色"), Category("自定义")]
71 public Color AxisColor
72 {
73 get { return axisColor; }
74 set
75 {
76 axisColor = value;
77 Refresh();
78 }
79 }
80
81 /// <summary>
82 /// The asis bottom color
83 /// </summary>
84 private Color asisBottomColor = Color.FromArgb(3, 169, 243);
85
86 /// <summary>
87 /// Gets or sets the color of the asis bottom.
88 /// </summary>
89 /// <value>The color of the asis bottom.</value>
90 [Description("轴底座颜色"), Category("自定义")]
91 public Color AsisBottomColor
92 {
93 get { return asisBottomColor; }
94 set { asisBottomColor = value; }
95 }
96
97 /// <summary>
98 /// The opened
99 /// </summary>
100 private bool opened = true;
101
102 /// <summary>
103 /// Gets or sets a value indicating whether this <see cref="UCValve" /> is opened.
104 /// </summary>
105 /// <value><c>true</c> if opened; otherwise, <c>false</c>.</value>
106 [Description("是否打开"), Category("自定义")]
107 public bool Opened
108 {
109 get { return opened; }
110 set
111 {
112 opened = value;
113 Refresh();
114 }
115 }
116
117 /// <summary>
118 /// The liquid direction
119 /// </summary>
120 private LiquidDirection liquidDirection = LiquidDirection.Forward;
121
122 /// <summary>
123 /// Gets or sets the liquid direction.
124 /// </summary>
125 /// <value>The liquid direction.</value>
126 [Description("液体流动方向"), Category("自定义")]
127 public LiquidDirection LiquidDirection
128 {
129 get { return liquidDirection; }
130 set
131 {
132 liquidDirection = value;
133 if (value == Conduit.LiquidDirection.None)
134 m_timer.Enabled = false;
135 else
136 m_timer.Enabled = true;
137 Refresh();
138 }
139 }
140
141 /// <summary>
142 /// The liquid speed
143 /// </summary>
144 private int liquidSpeed = 100;
145
146 /// <summary>
147 /// 液体流速,越小,速度越快Gets or sets the liquid speed.
148 /// </summary>
149 /// <value>The liquid speed.</value>
150 [Description("液体流速,越小,速度越快"), Category("自定义")]
151 public int LiquidSpeed
152 {
153 get { return liquidSpeed; }
154 set
155 {
156 if (value <= 0)
157 return;
158 liquidSpeed = value;
159 m_timer.Interval = value;
160 }
161 }
162
163 /// <summary>
164 /// The liquid color
165 /// </summary>
166 private Color liquidColor = Color.FromArgb(3, 169, 243);
167
168 /// <summary>
169 /// Gets or sets the color of the liquid.
170 /// </summary>
171 /// <value>The color of the liquid.</value>
172 [Description("液体颜色"), Category("自定义")]
173 public Color LiquidColor
174 {
175 get { return liquidColor; }
176 set
177 {
178 liquidColor = value;
179 if (liquidDirection != Conduit.LiquidDirection.None)
180 Refresh();
181 }
182 }
183 /// <summary>
184 /// The m timer
185 /// </summary>
186 Timer m_timer;
187 /// <summary>
188 /// The int line left
189 /// </summary>
190 int intLineLeft = 0;
重绘
1 protected override void OnPaint(PaintEventArgs e)
2 {
3 base.OnPaint(e);
4 var g = e.Graphics;
5 Rectangle rectGuan = Rectangle.Empty;//管道
6 Rectangle rectJK1 = Rectangle.Empty;//接口1
7 Rectangle rectJK2 = Rectangle.Empty;//接口2
8 Rectangle rectZ = Rectangle.Empty;//轴
9 GraphicsPath linePath = new GraphicsPath();//管道中心线
10 GraphicsPath dzPath = new GraphicsPath();//轴底座
11 GraphicsPath bsPath = new GraphicsPath();//开关把手
12 switch (valveStyle)
13 {
14 case ValveStyle.Horizontal_Top:
15 rectGuan = new Rectangle(0, this.Height / 2, this.Width, this.Height / 2 - this.Height / 8);
16 rectJK1 = new Rectangle(this.Height / 8, rectGuan.Top - this.Height / 8, rectGuan.Height / 2, rectGuan.Height + this.Height / 4);
17 rectJK2 = new Rectangle(rectGuan.Right - this.Height / 8 - rectGuan.Height / 2, rectGuan.Top - this.Height / 8, rectGuan.Height / 2, rectGuan.Height + this.Height / 4);
18 linePath.AddLine(new Point(rectGuan.Left - 10, rectGuan.Top + rectGuan.Height / 2), new Point(rectGuan.Right + 10, rectGuan.Top + rectGuan.Height / 2));
19 rectZ = new Rectangle(rectGuan.Left + (rectGuan.Width - rectGuan.Height / 4) / 2, 10, rectGuan.Height / 4, rectGuan.Top - 10);
20 Point[] psTop = new Point[]
21 {
22 new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height/2)/2,rectGuan.Top- this.Height / 8- 5 ),
23 new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height/2)/2,rectGuan.Top- this.Height / 8- 5 ),
24 new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height)/2,rectGuan.Top+2 ),
25 new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height)/2,rectGuan.Top +2),
26 };
27 dzPath.AddLines(psTop);
28 dzPath.CloseAllFigures();
29 if (opened)
30 {
31 bsPath.AddLine(rectGuan.Left + (rectGuan.Width - rectGuan.Height - 10) / 2, 10 + (rectGuan.Height / 3) / 2, rectGuan.Left + (rectGuan.Width - rectGuan.Height - 10) / 2 + rectGuan.Height + 10, 10 + (rectGuan.Height / 3) / 2);
32 }
33 else
34 {
35 bsPath.AddLine(new Point(rectGuan.Left + rectGuan.Width / 2 - 3, 1), new Point(rectGuan.Left + rectGuan.Width / 2 + 4, rectGuan.Height + 10));
36 }
37 break;
38 case ValveStyle.Horizontal_Bottom:
39 rectGuan = new Rectangle(0, this.Height / 8, this.Width, this.Height / 2 - this.Height / 8);
40 rectJK1 = new Rectangle(this.Height / 8, rectGuan.Top - this.Height / 8, rectGuan.Height / 2, rectGuan.Height + this.Height / 4);
41 rectJK2 = new Rectangle(rectGuan.Right - this.Height / 8 - rectGuan.Height / 2, rectGuan.Top - this.Height / 8, rectGuan.Height / 2, rectGuan.Height + this.Height / 4);
42 linePath.AddLine(new Point(rectGuan.Left - 10, rectGuan.Top + rectGuan.Height / 2), new Point(rectGuan.Right + 10, rectGuan.Top + rectGuan.Height / 2));
43 rectZ = new Rectangle(rectGuan.Left + (rectGuan.Width - rectGuan.Height / 4) / 2, rectGuan.Bottom + 10, rectGuan.Height / 4, this.Height - 10 - (rectGuan.Bottom + 10));
44 Point[] psBottom = new Point[]
45 {
46 new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height/2)/2,rectGuan.Bottom+ this.Height / 8+ 5 ),
47 new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height/2)/2,rectGuan.Bottom+ this.Height / 8+ 5 ),
48 new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height)/2,rectGuan.Bottom-2 ),
49 new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height)/2,rectGuan.Bottom-2),
50 };
51 dzPath.AddLines(psBottom);
52 dzPath.CloseAllFigures();
53 if (opened)
54 {
55 bsPath.AddLine(rectGuan.Left + (rectGuan.Width - rectGuan.Height - 10) / 2, this.Height - (10 + (rectGuan.Height / 3) / 2), rectGuan.Left + (rectGuan.Width - rectGuan.Height - 10) / 2 + rectGuan.Height + 10, this.Height - (10 + (rectGuan.Height / 3) / 2));
56 }
57 else
58 {
59 bsPath.AddLine(new Point(rectGuan.Left + rectGuan.Width / 2 - 3, this.Height - 1), new Point(rectGuan.Left + rectGuan.Width / 2 + 4, this.Height - (rectGuan.Height + 10)));
60 }
61 break;
62 case ValveStyle.Vertical_Left:
63 rectGuan = new Rectangle(this.Width / 8, 0, this.Width / 2 - this.Width / 8, this.Height);
64 rectJK1 = new Rectangle(0, this.Width / 8, rectGuan.Width + this.Width / 4, rectGuan.Width / 2);
65 rectJK2 = new Rectangle(0, this.Height - this.Width / 8 - rectGuan.Width / 2, rectGuan.Width + this.Width / 4, rectGuan.Width / 2);
66 linePath.AddLine(new Point(rectGuan.Left + rectGuan.Width / 2, rectGuan.Top - 10), new Point(rectGuan.Left + rectGuan.Width / 2, rectGuan.Bottom + 10));
67 rectZ = new Rectangle(rectGuan.Right, rectGuan.Top + (rectGuan.Height - rectGuan.Width / 4) / 2, rectGuan.Right - 10, rectGuan.Width / 4);
68 Point[] psLeft = new Point[]
69 {
70 new Point(rectGuan.Right+ this.Width / 8+ 5 ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / 2) / 2),
71 new Point(rectGuan.Right+ this.Width / 8+ 5 ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / 2) / 2+rectGuan.Width / 2),
72 new Point(rectGuan.Right-2, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/2+rectGuan.Width),
73 new Point(rectGuan.Right-2, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/2),
74 };
75 dzPath.AddLines(psLeft);
76 dzPath.CloseAllFigures();
77 if (opened)
78 {
79 bsPath.AddLine(this.Width - (10 + (rectGuan.Width / 3) / 2), rectGuan.Top + (rectGuan.Height - rectGuan.Width - 10) / 2, this.Width - (10 + (rectGuan.Width / 3) / 2), rectGuan.Top + (rectGuan.Height - rectGuan.Width - 10) / 2 + rectGuan.Width + 10);
80 }
81 else
82 {
83 bsPath.AddLine(new Point(this.Width - 1, rectGuan.Top + rectGuan.Height / 2 - 3), new Point(this.Width - (rectGuan.Width + 10), rectGuan.Top + rectGuan.Height / 2 + 4));
84 }
85 break;
86 case ValveStyle.Vertical_Right:
87 rectGuan = new Rectangle(this.Width - this.Width / 8 - (this.Width / 2 - this.Width / 8), 0, this.Width / 2 - this.Width / 8, this.Height);
88 rectJK1 = new Rectangle(this.Width - (rectGuan.Width + this.Width / 4), this.Width / 8, rectGuan.Width + this.Width / 4, rectGuan.Width / 2);
89 rectJK2 = new Rectangle(this.Width - (rectGuan.Width + this.Width / 4), this.Height - this.Width / 8 - rectGuan.Width / 2, rectGuan.Width + this.Width / 4, rectGuan.Width / 2);
90 linePath.AddLine(new Point(rectGuan.Left + rectGuan.Width / 2, rectGuan.Top - 10), new Point(rectGuan.Left + rectGuan.Width / 2, rectGuan.Bottom + 10));
91 rectZ = new Rectangle(10, rectGuan.Top + (rectGuan.Height - rectGuan.Width / 4) / 2, rectGuan.Left-10, rectGuan.Width / 4);
92 Point[] psRight = new Point[]
93 {
94 new Point(rectGuan.Left- (this.Width / 8+ 5) ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / 2) / 2),
95 new Point(rectGuan.Left-( this.Width / 8+ 5) ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / 2) / 2+rectGuan.Width / 2),
96 new Point(rectGuan.Left+2, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/2+rectGuan.Width),
97 new Point(rectGuan.Left+2, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/2),
98 };
99 dzPath.AddLines(psRight);
100 dzPath.CloseAllFigures();
101
102 if (opened)
103 {
104 bsPath.AddLine( (10 + (rectGuan.Width / 3) / 2), rectGuan.Top + (rectGuan.Height - rectGuan.Width - 10) / 2, (10 + (rectGuan.Width / 3) / 2), rectGuan.Top + (rectGuan.Height - rectGuan.Width - 10) / 2 + rectGuan.Width + 10);
105 }
106 else
107 {
108 bsPath.AddLine(new Point( 1, rectGuan.Top + rectGuan.Height / 2 - 3), new Point( (rectGuan.Width + 10), rectGuan.Top + rectGuan.Height / 2 + 4));
109 }
110 break;
111 }
112
113 //管道
114 g.FillRectangle(new SolidBrush(valveColor), rectGuan);
115 //接口
116 g.FillRectangle(new SolidBrush(valveColor), rectJK1);
117 g.FillRectangle(new SolidBrush(Color.FromArgb(40, Color.White)), rectJK1);
118 g.FillRectangle(new SolidBrush(valveColor), rectJK2);
119 g.FillRectangle(new SolidBrush(Color.FromArgb(40, Color.White)), rectJK2);
120
121
122 //高亮
123 int intCount = (valveStyle.ToString().StartsWith("H") ? rectGuan.Height : rectGuan.Width) / 2 / 4;
124 for (int i = 0; i < intCount; i++)
125 {
126 int _penWidth = (valveStyle.ToString().StartsWith("H") ? rectGuan.Height : rectGuan.Width) / 2 - 4 * i;
127 if (_penWidth <= 0)
128 _penWidth = 1;
129 g.DrawPath(new Pen(new SolidBrush(Color.FromArgb(40, Color.White.R, Color.White.G, Color.White.B)), _penWidth), linePath);
130 if (_penWidth == 1)
131 break;
132 }
133
134 g.SetGDIHigh();
135 //轴
136 g.FillRectangle(new SolidBrush(axisColor), rectZ);
137
138 //阀门底座
139 g.FillPath(new SolidBrush(asisBottomColor), dzPath);
140 g.FillPath(new SolidBrush(Color.FromArgb(50, Color.White)), dzPath);
141
142 //把手
143 g.DrawPath(new Pen(new SolidBrush(switchColor), (valveStyle.ToString().StartsWith("H") ? rectGuan.Height : rectGuan.Width) / 3), bsPath);
144
145 //液体流动
146 if (opened)
147 {
148 Pen p = new Pen(new SolidBrush(liquidColor), 4);
149 p.DashPattern = new float[] { 6, 6 };
150 p.DashOffset = intLineLeft * (LiquidDirection == Conduit.LiquidDirection.Forward ? -1 : 1);
151 g.DrawPath(p, linePath);
152 }
153 }
全部代码
// ***********************************************************************
// Assembly : HZH_Controls
// Created : 2019-09-06
//
// ***********************************************************************
// <copyright file="UCValve.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 HZH_Controls.Controls.Conduit;
using System.ComponentModel;
namespace HZH_Controls.Controls
{
/// <summary>
/// Class UCValve.
/// Implements the <see cref="System.Windows.Forms.UserControl" />
/// </summary>
/// <seealso cref="System.Windows.Forms.UserControl" />
public class UCValve : UserControl
{
/// <summary>
/// The valve style
/// </summary>
private ValveStyle valveStyle = ValveStyle.Horizontal_Top;
/// <summary>
/// Gets or sets the valve style.
/// </summary>
/// <value>The valve style.</value>
[Description("阀门样式"), Category("自定义")]
public ValveStyle ValveStyle
{
get { return valveStyle; }
set
{
valveStyle = value;
Refresh();
}
}
/// <summary>
/// The valve color
/// </summary>
private Color valveColor = Color.FromArgb(255, 77, 59);
/// <summary>
/// Gets or sets the color of the valve.
/// </summary>
/// <value>The color of the valve.</value>
[Description("阀门颜色"), Category("自定义")]
public Color ValveColor
{
get { return valveColor; }
set
{
valveColor = value;
Refresh();
}
}
/// <summary>
/// The switch color
/// </summary>
private Color switchColor = Color.FromArgb(232, 30, 99);
/// <summary>
/// Gets or sets the color of the switch.
/// </summary>
/// <value>The color of the switch.</value>
[Description("开关把手颜色"), Category("自定义")]
public Color SwitchColor
{
get { return switchColor; }
set
{
switchColor = value;
Refresh();
}
}
/// <summary>
/// The axis color
/// </summary>
private Color axisColor = Color.FromArgb(3, 169, 243);
/// <summary>
/// Gets or sets the color of the axis.
/// </summary>
/// <value>The color of the axis.</value>
[Description("轴颜色"), Category("自定义")]
public Color AxisColor
{
get { return axisColor; }
set
{
axisColor = value;
Refresh();
}
}
/// <summary>
/// The asis bottom color
/// </summary>
private Color asisBottomColor = Color.FromArgb(3, 169, 243);
/// <summary>
/// Gets or sets the color of the asis bottom.
/// </summary>
/// <value>The color of the asis bottom.</value>
[Description("轴底座颜色"), Category("自定义")]
public Color AsisBottomColor
{
get { return asisBottomColor; }
set { asisBottomColor = value; }
}
/// <summary>
/// The opened
/// </summary>
private bool opened = true;
/// <summary>
/// Gets or sets a value indicating whether this <see cref="UCValve" /> is opened.
/// </summary>
/// <value><c>true</c> if opened; otherwise, <c>false</c>.</value>
[Description("是否打开"), Category("自定义")]
public bool Opened
{
get { return opened; }
set
{
opened = value;
Refresh();
}
}
/// <summary>
/// The liquid direction
/// </summary>
private LiquidDirection liquidDirection = LiquidDirection.Forward;
/// <summary>
/// Gets or sets the liquid direction.
/// </summary>
/// <value>The liquid direction.</value>
[Description("液体流动方向"), Category("自定义")]
public LiquidDirection LiquidDirection
{
get { return liquidDirection; }
set
{
liquidDirection = value;
if (value == Conduit.LiquidDirection.None)
m_timer.Enabled = false;
else
m_timer.Enabled = true;
Refresh();
}
}
/// <summary>
/// The liquid speed
/// </summary>
private int liquidSpeed = 100;
/// <summary>
/// 液体流速,越小,速度越快Gets or sets the liquid speed.
/// </summary>
/// <value>The liquid speed.</value>
[Description("液体流速,越小,速度越快"), Category("自定义")]
public int LiquidSpeed
{
get { return liquidSpeed; }
set
{
if (value <= 0)
return;
liquidSpeed = value;
m_timer.Interval = value;
}
}
/// <summary>
/// The liquid color
/// </summary>
private Color liquidColor = Color.FromArgb(3, 169, 243);
/// <summary>
/// Gets or sets the color of the liquid.
/// </summary>
/// <value>The color of the liquid.</value>
[Description("液体颜色"), Category("自定义")]
public Color LiquidColor
{
get { return liquidColor; }
set
{
liquidColor = value;
if (liquidDirection != Conduit.LiquidDirection.None)
Refresh();
}
}
/// <summary>
/// The m timer
/// </summary>
Timer m_timer;
/// <summary>
/// The int line left
/// </summary>
int intLineLeft = 0;
/// <summary>
/// Initializes a new instance of the <see cref="UCValve" /> class.
/// </summary>
public UCValve()
{
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.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Size = new Size(120, 100);
m_timer = new Timer();
m_timer.Interval = 100;
m_timer.Tick += timer_Tick;
m_timer.Enabled = true;
}
/// <summary>
/// Handles the Tick event of the timer control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
void timer_Tick(object sender, EventArgs e)
{
intLineLeft += 2;
if (intLineLeft > 12)
intLineLeft = 0;
Refresh();
}
/// <summary>
/// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
/// </summary>
/// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param>
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var g = e.Graphics;
Rectangle rectGuan = Rectangle.Empty;//管道
Rectangle rectJK1 = Rectangle.Empty;//接口1
Rectangle rectJK2 = Rectangle.Empty;//接口2
Rectangle rectZ = Rectangle.Empty;//轴
GraphicsPath linePath = new GraphicsPath();//管道中心线
GraphicsPath dzPath = new GraphicsPath();//轴底座
GraphicsPath bsPath = new GraphicsPath();//开关把手
switch (valveStyle)
{
case ValveStyle.Horizontal_Top:
rectGuan = new Rectangle(0, this.Height / 2, this.Width, this.Height / 2 - this.Height / 8);
rectJK1 = new Rectangle(this.Height / 8, rectGuan.Top - this.Height / 8, rectGuan.Height / 2, rectGuan.Height + this.Height / 4);
rectJK2 = new Rectangle(rectGuan.Right - this.Height / 8 - rectGuan.Height / 2, rectGuan.Top - this.Height / 8, rectGuan.Height / 2, rectGuan.Height + this.Height / 4);
linePath.AddLine(new Point(rectGuan.Left - 10, rectGuan.Top + rectGuan.Height / 2), new Point(rectGuan.Right + 10, rectGuan.Top + rectGuan.Height / 2));
rectZ = new Rectangle(rectGuan.Left + (rectGuan.Width - rectGuan.Height / 4) / 2, 10, rectGuan.Height / 4, rectGuan.Top - 10);
Point[] psTop = new Point[]
{
new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height/2)/2,rectGuan.Top- this.Height / 8- 5 ),
new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height/2)/2,rectGuan.Top- this.Height / 8- 5 ),
new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height)/2,rectGuan.Top+2 ),
new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height)/2,rectGuan.Top +2),
};
dzPath.AddLines(psTop);
dzPath.CloseAllFigures();
if (opened)
{
bsPath.AddLine(rectGuan.Left + (rectGuan.Width - rectGuan.Height - 10) / 2, 10 + (rectGuan.Height / 3) / 2, rectGuan.Left + (rectGuan.Width - rectGuan.Height - 10) / 2 + rectGuan.Height + 10, 10 + (rectGuan.Height / 3) / 2);
}
else
{
bsPath.AddLine(new Point(rectGuan.Left + rectGuan.Width / 2 - 3, 1), new Point(rectGuan.Left + rectGuan.Width / 2 + 4, rectGuan.Height + 10));
}
break;
case ValveStyle.Horizontal_Bottom:
rectGuan = new Rectangle(0, this.Height / 8, this.Width, this.Height / 2 - this.Height / 8);
rectJK1 = new Rectangle(this.Height / 8, rectGuan.Top - this.Height / 8, rectGuan.Height / 2, rectGuan.Height + this.Height / 4);
rectJK2 = new Rectangle(rectGuan.Right - this.Height / 8 - rectGuan.Height / 2, rectGuan.Top - this.Height / 8, rectGuan.Height / 2, rectGuan.Height + this.Height / 4);
linePath.AddLine(new Point(rectGuan.Left - 10, rectGuan.Top + rectGuan.Height / 2), new Point(rectGuan.Right + 10, rectGuan.Top + rectGuan.Height / 2));
rectZ = new Rectangle(rectGuan.Left + (rectGuan.Width - rectGuan.Height / 4) / 2, rectGuan.Bottom + 10, rectGuan.Height / 4, this.Height - 10 - (rectGuan.Bottom + 10));
Point[] psBottom = new Point[]
{
new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height/2)/2,rectGuan.Bottom+ this.Height / 8+ 5 ),
new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height/2)/2,rectGuan.Bottom+ this.Height / 8+ 5 ),
new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height)/2,rectGuan.Bottom-2 ),
new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height)/2,rectGuan.Bottom-2),
};
dzPath.AddLines(psBottom);
dzPath.CloseAllFigures();
if (opened)
{
bsPath.AddLine(rectGuan.Left + (rectGuan.Width - rectGuan.Height - 10) / 2, this.Height - (10 + (rectGuan.Height / 3) / 2), rectGuan.Left + (rectGuan.Width - rectGuan.Height - 10) / 2 + rectGuan.Height + 10, this.Height - (10 + (rectGuan.Height / 3) / 2));
}
else
{
bsPath.AddLine(new Point(rectGuan.Left + rectGuan.Width / 2 - 3, this.Height - 1), new Point(rectGuan.Left + rectGuan.Width / 2 + 4, this.Height - (rectGuan.Height + 10)));
}
break;
case ValveStyle.Vertical_Left:
rectGuan = new Rectangle(this.Width / 8, 0, this.Width / 2 - this.Width / 8, this.Height);
rectJK1 = new Rectangle(0, this.Width / 8, rectGuan.Width + this.Width / 4, rectGuan.Width / 2);
rectJK2 = new Rectangle(0, this.Height - this.Width / 8 - rectGuan.Width / 2, rectGuan.Width + this.Width / 4, rectGuan.Width / 2);
linePath.AddLine(new Point(rectGuan.Left + rectGuan.Width / 2, rectGuan.Top - 10), new Point(rectGuan.Left + rectGuan.Width / 2, rectGuan.Bottom + 10));
rectZ = new Rectangle(rectGuan.Right, rectGuan.Top + (rectGuan.Height - rectGuan.Width / 4) / 2, rectGuan.Right - 10, rectGuan.Width / 4);
Point[] psLeft = new Point[]
{
new Point(rectGuan.Right+ this.Width / 8+ 5 ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / 2) / 2),
new Point(rectGuan.Right+ this.Width / 8+ 5 ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / 2) / 2+rectGuan.Width / 2),
new Point(rectGuan.Right-2, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/2+rectGuan.Width),
new Point(rectGuan.Right-2, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/2),
};
dzPath.AddLines(psLeft);
dzPath.CloseAllFigures();
if (opened)
{
bsPath.AddLine(this.Width - (10 + (rectGuan.Width / 3) / 2), rectGuan.Top + (rectGuan.Height - rectGuan.Width - 10) / 2, this.Width - (10 + (rectGuan.Width / 3) / 2), rectGuan.Top + (rectGuan.Height - rectGuan.Width - 10) / 2 + rectGuan.Width + 10);
}
else
{
bsPath.AddLine(new Point(this.Width - 1, rectGuan.Top + rectGuan.Height / 2 - 3), new Point(this.Width - (rectGuan.Width + 10), rectGuan.Top + rectGuan.Height / 2 + 4));
}
break;
case ValveStyle.Vertical_Right:
rectGuan = new Rectangle(this.Width - this.Width / 8 - (this.Width / 2 - this.Width / 8), 0, this.Width / 2 - this.Width / 8, this.Height);
rectJK1 = new Rectangle(this.Width - (rectGuan.Width + this.Width / 4), this.Width / 8, rectGuan.Width + this.Width / 4, rectGuan.Width / 2);
rectJK2 = new Rectangle(this.Width - (rectGuan.Width + this.Width / 4), this.Height - this.Width / 8 - rectGuan.Width / 2, rectGuan.Width + this.Width / 4, rectGuan.Width / 2);
linePath.AddLine(new Point(rectGuan.Left + rectGuan.Width / 2, rectGuan.Top - 10), new Point(rectGuan.Left + rectGuan.Width / 2, rectGuan.Bottom + 10));
rectZ = new Rectangle(10, rectGuan.Top + (rectGuan.Height - rectGuan.Width / 4) / 2, rectGuan.Left-10, rectGuan.Width / 4);
Point[] psRight = new Point[]
{
new Point(rectGuan.Left- (this.Width / 8+ 5) ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / 2) / 2),
new Point(rectGuan.Left-( this.Width / 8+ 5) ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / 2) / 2+rectGuan.Width / 2),
new Point(rectGuan.Left+2, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/2+rectGuan.Width),
new Point(rectGuan.Left+2, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/2),
};
dzPath.AddLines(psRight);
dzPath.CloseAllFigures();
if (opened)
{
bsPath.AddLine( (10 + (rectGuan.Width / 3) / 2), rectGuan.Top + (rectGuan.Height - rectGuan.Width - 10) / 2, (10 + (rectGuan.Width / 3) / 2), rectGuan.Top + (rectGuan.Height - rectGuan.Width - 10) / 2 + rectGuan.Width + 10);
}
else
{
bsPath.AddLine(new Point( 1, rectGuan.Top + rectGuan.Height / 2 - 3), new Point( (rectGuan.Width + 10), rectGuan.Top + rectGuan.Height / 2 + 4));
}
break;
}
//管道
g.FillRectangle(new SolidBrush(valveColor), rectGuan);
//接口
g.FillRectangle(new SolidBrush(valveColor), rectJK1);
g.FillRectangle(new SolidBrush(Color.FromArgb(40, Color.White)), rectJK1);
g.FillRectangle(new SolidBrush(valveColor), rectJK2);
g.FillRectangle(new SolidBrush(Color.FromArgb(40, Color.White)), rectJK2);
//高亮
int intCount = (valveStyle.ToString().StartsWith("H") ? rectGuan.Height : rectGuan.Width) / 2 / 4;
for (int i = 0; i < intCount; i++)
{
int _penWidth = (valveStyle.ToString().StartsWith("H") ? rectGuan.Height : rectGuan.Width) / 2 - 4 * i;
if (_penWidth <= 0)
_penWidth = 1;
g.DrawPath(new Pen(new SolidBrush(Color.FromArgb(40, Color.White.R, Color.White.G, Color.White.B)), _penWidth), linePath);
if (_penWidth == 1)
break;
}
g.SetGDIHigh();
//轴
g.FillRectangle(new SolidBrush(axisColor), rectZ);
//阀门底座
g.FillPath(new SolidBrush(asisBottomColor), dzPath);
g.FillPath(new SolidBrush(Color.FromArgb(50, Color.White)), dzPath);
//把手
g.DrawPath(new Pen(new SolidBrush(switchColor), (valveStyle.ToString().StartsWith("H") ? rectGuan.Height : rectGuan.Width) / 3), bsPath);
//液体流动
if (opened)
{
Pen p = new Pen(new SolidBrush(liquidColor), 4);
p.DashPattern = new float[] { 6, 6 };
p.DashOffset = intLineLeft * (LiquidDirection == Conduit.LiquidDirection.Forward ? -1 : 1);
g.DrawPath(p, linePath);
}
}
}
/// <summary>
/// Enum ValveStyle
/// </summary>
public enum ValveStyle
{
/// <summary>
/// 横向,开关在上方
/// </summary>
Horizontal_Top,
/// <summary>
/// 横向,开关在下方
/// </summary>
Horizontal_Bottom,
/// <summary>
/// 纵向,开关在左侧
/// </summary>
Vertical_Left,
/// <summary>
/// 纵向,开关在右侧
/// </summary>
Vertical_Right,
}
}