写了一个windows窗体控件库,画板的大小是130,130.我在画板上做了一个仪表盘,把dll文件放到我要用的项目中,然后我拖动这个控件的边框,原本以为会向其他控件一样变大变小,实际上确实如图的效果。我怎么才能实现拖动边框就能变大变小这个功能呢?
附上控件源码


附上控件源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
|
using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Drawing;
using
System.Data;
using
System.Linq;
using
System.Text;
using
System.Windows.Forms;
using
System.Drawing.Drawing2D;
using
System.Threading;
namespace
MyMeter
{
public
partial
class
Meter : UserControl
{
string
_unitStr =
""
;
int
_diameter = 130;
int
_PinLen = 50;
int
safeValue = 80;
int
typeSize = 12;
int
markSize = 10;
float
sAngleGreen = 45;
float
sAngleRed = 315;
float
sweepAngleGreen = 270;
double
_maxValue = 120;
double
_changeValue = 0;
Color safeColor = Color.Green;
Color _pinColor = Color.Black;
Color _frameColor = Color.Black;
StringFormat strFormat =
new
StringFormat();
public
Meter()
{
InitializeComponent();
UpdateStyles();
DrawBackImg();
pic.Invalidate();
strFormat.Alignment = StringAlignment.Center;
strFormat.LineAlignment = StringAlignment.Center;
}
//直径
public
int
DiaMeter
{
get
{
return
_diameter; }
set
{
_diameter = value - 1;
this
.Width =
this
.Height = value;
DrawBackImg();
pic.Invalidate();
}
}
//最大值
public
double
MaxValue
{
get
{
return
_maxValue; }
set
{
_maxValue = value;
DrawBackImg();
}
}
public
double
ChangeValue
{
get
{
return
_changeValue; }
set
{
if
(value > _maxValue)
{
_maxValue = value;
}
this
.tmChangvalue = value;
startDraw();
}
}
//针的长度
public
int
PinLen
{
get
{
return
_PinLen; }
set
{ _PinLen = value; pic.Invalidate(); }
}
public
int
NxPinLen
{
get
{
return
(
int
)(_PinLen / 5); }
}
public
Color PinColor
{
get
{
return
_pinColor; }
set
{ _pinColor = value; pic.Invalidate(); DrawBackImg(); }
}
public
Color FrameColor
{
get
{
return
_frameColor; }
set
{ _frameColor = value; DrawBackImg(); }
}
public
string
UnitStr
{
get
{
return
_unitStr; }
set
{ _unitStr = value; DrawBackImg(); pic.Invalidate(); }
}
public
int
SafeValue
{
get
{
return
safeValue; }
set
{
safeValue = value;
startDraw();
}
}
public
Color SafeColor
{
get
{
return
safeColor; }
set
{
safeColor = value;
DrawBackImg();
pic.Invalidate();
}
}
//字体大小
public
int
TypeSize
{
get
{
return
typeSize; }
set
{
typeSize = value;
}
}
public
int
MarkSize
{
get
{
return
markSize; }
set
{
markSize = value;
}
}
public
float
startAngleGreen
{
get
{
return
sAngleGreen; }
set
{
sAngleGreen = value;
DrawBackImg();
}
}
public
float
startAngleRed
{
get
{
return
sAngleRed; }
set
{
sAngleRed = value;
DrawBackImg();
}
}
public
float
SweepAngleGreen
{
get
{
return
sweepAngleGreen; }
set
{
sweepAngleGreen = value;
DrawBackImg();
}
}
//背景颜色
public
bool
_isDrawBackGround =
false
;
public
bool
IsDrawBackGround
{
get
{
return
_isDrawBackGround; }
set
{ _isDrawBackGround = value; DrawBackImg(); }
}
//渐变颜色
public
Color _centerColor = Color.White;
public
Color CenterColor
{
get
{
return
_centerColor; }
set
{ _centerColor = value; DrawBackImg(); }
}
//外部颜色
public
Color _borderColor = Color.White;
public
Color BorderColor
{
get
{
return
_borderColor; }
set
{ _borderColor = value; DrawBackImg(); }
}
public
void
Clear()
{
_changeValue = 0;
this
.Invalidate();
}
double
tmChangvalue = 0;
double
valueSpan = 0.1;
public
void
startDraw()
{
Thread threadDraw =
new
Thread(
new
ThreadStart(drawTrhead));
threadDraw.IsBackground =
false
;
threadDraw.Start();
}
public
void
drawTrhead()
{
//改变量
//_changeValue = 0;
double
tmp = tmChangvalue - _changeValue;
if
(tmp > 0)
{
for
(
double
j = 0; j <= tmp; )
{
j += valueSpan;
if
(_changeValue + valueSpan < tmChangvalue)
//if (_changeValue + valueSpan < _maxValue)
{
_changeValue += valueSpan;
}
Thread.Sleep(1);
this
.Invalidate();
}
}
else
{
for
(
double
j = 0; j < -tmp; )
{
j += valueSpan;
if
(_changeValue - valueSpan > 0)
{
_changeValue -= valueSpan;
}
Thread.Sleep(1);
this
.Invalidate();
}
}
}
public
void
DrawForeImg(Graphics gp)
{
Bitmap bit =
new
Bitmap(
this
.Width,
this
.Height);
Graphics g = Graphics.FromImage(bit);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//画针
DrawPin(g);
//画点
drawPoint(g);
//显示示数
DrawString(g);
gp.DrawImage(bit,
new
Point(0, 0));
g.Dispose();
}
//画针
public
void
DrawPin(Graphics g)
{
int
cer = _diameter / 2;
float
start = 135;
float
sweepShot = (
float
)(_changeValue / _maxValue * 270.0);
//float sweepShot = (float)(55 / _maxValue * 270.0);
Pen lineGPen =
new
Pen(Color.Green, 1);
Pen NxGPen =
new
Pen(Color.Green, 3);
Pen xGPen =
new
Pen(Color.Green, 5);
Pen lineRPen =
new
Pen(Color.Red, 1);
Pen NxRPen =
new
Pen(Color.Red, 3);
Pen xRPen =
new
Pen(Color.Red, 5);
double
rad = (sweepShot + start) * Math.PI / 180;
//float radius = _diameter / 2 - 5;
int
dx = (
int
)(cer + (_PinLen) * Math.Cos(rad));
int
dy = (
int
)(cer + (_PinLen) * Math.Sin(rad));
int
px = (
int
)(cer + (_PinLen * 0.4) * Math.Cos(rad));
int
py = (
int
)(cer + (_PinLen * 0.4) * Math.Sin(rad));
int
nx = (
int
)(cer - (NxPinLen) * Math.Sin(rad));
int
ny = (
int
)(cer - (NxPinLen) * Math.Cos(rad));
/*SolidBrush brushRed = new SolidBrush(Color.Red);
SolidBrush brushGreen = new SolidBrush(Color.Green);
//b1x=68
int b1x = (int)(cer - 5 * Math.Cos(rad));
//b1y=62
int b1y = (int)(cer - 4 * Math.Sin(rad));
int b2x = (int)(cer + 4 * Math.Cos(rad));
int b2y = (int)(cer + 5 * Math.Sin(rad));
PointF point1 = new PointF(b2y, b1x);
PointF point2 = new PointF(b1y, b2x);
PointF point3 = new PointF(dx, dy);
PointF[] curvePoints = { point1, point2, point3 };*/
//总共6等分的sweepShot=0的时候就是仪表盘上的0
//然后依次加45就是第二个刻度数,总共270,正上方为135
if
(sweepShot < 180)
{
g.DrawLine(lineGPen,
new
Point(cer, cer),
new
Point(dx, dy));
g.DrawLine(NxGPen,
new
Point(cer, cer),
new
Point(px, py));
g.DrawLine(xGPen,
new
Point(cer, cer),
new
Point(ny, nx));
//g.FillPolygon(brushGreen, curvePoints);
}
else
{
g.DrawLine(lineRPen,
new
Point(cer, cer),
new
Point(dx, dy));
g.DrawLine(NxRPen,
new
Point(cer, cer),
new
Point(px, py));
g.DrawLine(xRPen,
new
Point(cer, cer),
new
Point(ny, nx));
//g.FillPolygon(brushRed, curvePoints);
}
//设置清理缓存的
//EnableDoubleBuffering();
}
//显示当前压力
public
void
DrawString(Graphics g)
{
int
cer = _diameter / 2;
//F0表示浮点数小数点后面没有数字 F2表示精确到小数点后2位
string
str = _changeValue.ToString(
"F0"
);
if
(Convert.ToInt16(str) >= safeValue)
{
safeColor = Color.Red;
}
else
{
safeColor = Color.Green;
}
g.DrawString(str,
new
Font(
"宋体"
, typeSize),
new
SolidBrush(safeColor),
new
PointF(cer, (
float
)(cer + cer * 0.3)), strFormat);
}
//框架
//背景
public
void
DrawBackImg()
{
Bitmap bit =
new
Bitmap(
this
.Width,
this
.Height);
Graphics gp = Graphics.FromImage(bit);
gp.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
if
(_isDrawBackGround)
{
//背景渐变色
drawBachground(gp);
}
//外框 一个圆圈
drawFrame(gp);
// 画刻度
DrawRuling(gp);
//单位
DrawUnitStr(gp);
//画点
//drawPoint(gp);
this
.BackgroundImage = bit;
}
//单位
public
void
DrawUnitStr(Graphics gp)
{
int
cer = _diameter / 2;
gp.DrawString(_unitStr,
new
Font(
"宋体"
, 10),
new
SolidBrush(_frameColor),
new
PointF(cer, (
float
)(cer - cer * 0.3)), strFormat);
}
/// <summary>
/// 画外框
/// </summary>
/// <param name="gp"></param>
public
void
drawFrame(Graphics gp)
{
Pen p =
new
Pen(Color.Black, 3);
Rectangle rec =
new
Rectangle(5, 5, _diameter - 10, _diameter - 10);
//SolidBrush sdBrush2 = new SolidBrush(Color.Black);
//gp.DrawEllipse(p, rec);
//gp.FillEllipse(sdBrush2, 5, 5, _diameter - 10, _diameter - 10);
Pen pgreen =
new
Pen(Color.Green, 2);
Pen pred =
new
Pen(Color.Red, 2);
gp.DrawArc(pgreen, rec, sAngleGreen, sweepAngleGreen);
gp.DrawArc(pred, rec, sAngleRed, 360 - sweepAngleGreen);
//引用的图片
/*Rectangle rec = new Rectangle(0, 0, _diameter, _diameter);
TextureBrush pic = new TextureBrush(Image.FromFile(@"f:\picture\121-5.png"));
gp.FillRectangle(pic, rec);*/
}
/// <summary>
/// 画刻度
/// </summary>
/// <param name="gp"></param>
public
void
DrawRuling(Graphics gp)
{
//刻度
bool
isGreen =
true
;
int
cerX = _diameter / 2;
int
cerY = _diameter / 2;
int
dx = 0;
int
dy = 0;
//刻度长度
int
soildLenght = 8;
//刻度下数字位置
float
start = 135;
float
sweepShot = 0;
float
span = (
float
)(_maxValue / 30);
float
sp = 0;
//刻度颜色
Pen linePen =
new
Pen(_frameColor, 1);
//用于右边数字右对齐
StringFormat stf =
new
StringFormat();
stf.Alignment = StringAlignment.Far;
StringFormat stfMid =
new
StringFormat();
stfMid.Alignment = StringAlignment.Center;
stfMid.LineAlignment = StringAlignment.Center;
for
(
int
i = 0; i <= 30; i++)
{
double
rad = (sweepShot + start) * Math.PI / 180;
float
radius = _diameter / 2 - 5;
int
px = (
int
)(cerX + radius * Math.Cos(rad));
int
py = (
int
)(cerY + radius * Math.Sin(rad));
if
(sweepShot % 5 == 0)
{
linePen.Width = 2;
dx = (
int
)(cerX + (radius - soildLenght) * Math.Cos(rad));
dy = (
int
)(cerY + (radius - soildLenght) * Math.Sin(rad));
string
str = sp.ToString(
"f0"
);
if
(sweepShot <= 45)
{
gp.DrawString(str,
new
Font(
"宋体"
, MarkSize),
new
SolidBrush(Color.Green),
new
PointF(dx, dy - 5));
isGreen =
true
;
}
//else if (sweepShot == 90)
else
if
(sweepShot > 45 && sweepShot < 135)
{
gp.DrawString(str,
new
Font(
"宋体"
, MarkSize),
new
SolidBrush(Color.Green),
new
PointF(dx, dy));
isGreen =
true
;
}
else
if
(sweepShot == 135)
{
//仪表盘正上方
gp.DrawString(str,
new
Font(
"宋体"
, MarkSize),
new
SolidBrush(Color.Green),
new
PointF(dx, dy + 10), stfMid);
isGreen =
true
;
}
else
if
(sweepShot > 135 && sweepShot < 225)
{
//仪表盘第五个数字
gp.DrawString(str,
new
Font(
"宋体"
, MarkSize),
new
SolidBrush(Color.Red),
new
PointF(dx, dy), stf);
isGreen =
false
;
}
else
if
(sweepShot >= 225)
{
//仪表盘第六第七个
gp.DrawString(str,
new
Font(
"宋体"
, MarkSize),
new
SolidBrush(Color.Red),
new
PointF(dx, dy - 5), stf);
isGreen =
false
;
}
}
else
{
linePen.Width = 1;
dx = (
int
)(cerX + (radius - soildLenght + 2) * Math.Cos(rad));
dy = (
int
)(cerY + (radius - soildLenght + 2) * Math.Sin(rad));
}
if
(isGreen)
{
Pen p =
new
Pen(Color.Green, 1);
gp.DrawLine(p,
new
Point(px, py),
new
Point(dx, dy));
sp += span;
sweepShot += 9;
}
else
{
Pen p =
new
Pen(Color.Red, 1);
gp.DrawLine(p,
new
Point(px, py),
new
Point(dx, dy));
sp += span;
sweepShot += 9;
}
}
}
//画中间的点
public
void
drawPoint(Graphics gp)
{
Color circlrColor = Color.Black;
Pen pG =
new
Pen(Color.Green);
Pen pR =
new
Pen(Color.Red);
int
tmpWidth = 7;
int
px = _diameter / 2 - tmpWidth;
float
sweepShot = (
float
)(_changeValue / _maxValue * 270.0);
//总共6等分的sweepShot=0的时候就是仪表盘上的0
//然后依次加45就是第二个刻度数,总共270,正上方为135
if
(sweepShot < 180)
{
gp.DrawEllipse(pG,
new
Rectangle(px, px, 2 * tmpWidth, 2 * tmpWidth));
gp.FillEllipse(
new
SolidBrush(Color.Green),
new
Rectangle(px + 2, px + 2, 2 * tmpWidth - 4, 2 * tmpWidth - 4));
//gp.FillEllipse(new SolidBrush(Color.Green), new Rectangle(px, px, 2 * tmpWidth, 2 * tmpWidth));
}
else
{
gp.DrawEllipse(pR,
new
Rectangle(px, px, 2 * tmpWidth, 2 * tmpWidth));
gp.FillEllipse(
new
SolidBrush(Color.Red),
new
Rectangle(px + 2, px + 2, 2 * tmpWidth - 4, 2 * tmpWidth - 4));
//gp.FillEllipse(new SolidBrush(Color.Red), new Rectangle(px, px, 2 * tmpWidth, 2 * tmpWidth));
}
//gp.FillEllipse(new SolidBrush(Color.Red), new Rectangle(px, px, 2 * tmpWidth, 2 * tmpWidth));
//gp.DrawRectangle(p, new Rectangle(px, px, 2 * tmpWidth, 2 * tmpWidth));
}
// 设置为双缓冲,防止刷新时闪烁
public
void
EnableDoubleBuffering()
{
// Set the value of the double-buffering style bits to true.
this
.SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint,
true
);
this
.UpdateStyles();
}
//画背景渐变色
public
void
drawBachground(Graphics gp)
{
GraphicsPath path =
new
GraphicsPath();
path.AddEllipse(3, 3, _diameter - 6, _diameter - 6);
PathGradientBrush pthGrBrush =
new
PathGradientBrush(path);
pthGrBrush.CenterColor = _centerColor;
Color[] colors = { _borderColor };
pthGrBrush.SurroundColors = colors;
gp.FillEllipse(pthGrBrush, 3, 3, _diameter - 6, _diameter - 6);
}
public
void
pic_Paint(
object
sender, PaintEventArgs e)
{
DrawForeImg(e.Graphics);
}
}
}
|