当前位置:首页 > C#教程 > C#高级

(七十一)c#Winform自定义控件-折线图

前提

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

GitHub:https://github.com/kwwwvagaa/NetWinformControl

码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

如果觉得写的还行,请点个 star 支持一下吧

欢迎前来交流探讨: 企鹅群568015492 技术分享图片

麻烦博客下方点个【推荐】,谢谢

NuGet

Install-Package HZH_Controls

目录

https://www.cnblogs.com/bfyx/p/11364884.html

用处及效果

技术分享图片

技术分享图片

技术分享图片

准备工作

请先了解GDI+相关知识

开始

添加一个类UCCurve 继承自UserControl

添加一些控制属性

              1
            ///
            <summary>
              2
            ///
             The value count maximum

              3
            ///
            </summary>
              4
            private
            const
            int value_count_max = 4096;
  5  6///<summary>  7/// The value maximum left
  8///</summary>  9privatefloat value_max_left = 100f;
 10 11///<summary> 12/// The value minimum left
 13///</summary> 14privatefloat value_min_left = 0f;
 15 16///<summary> 17/// The value maximum right
 18///</summary> 19privatefloat value_max_right = 100f;
 20 21///<summary> 22/// The value minimum right
 23///</summary> 24privatefloat value_min_right = 0f;
 25 26///<summary> 27/// The value segment
 28///</summary> 29privateint value_Segment = 5;
 30 31///<summary> 32/// The value is abscissa strech
 33///</summary> 34privatebool value_IsAbscissaStrech = false;
 35 36///<summary> 37/// The value strech data count maximum
 38///</summary> 39privateint value_StrechDataCountMax = 300;
 40 41///<summary> 42/// The value is render dash line
 43///</summary> 44privatebool value_IsRenderDashLine = true;
 45 46///<summary> 47/// The text format
 48///</summary> 49privatestring textFormat = "HH:mm";
 50 51///<summary> 52/// The value interval abscissa text
 53///</summary> 54privateint value_IntervalAbscissaText = 100;
 55 56///<summary> 57/// The random
 58///</summary> 59private Random random = null;
 60 61///<summary> 62/// The value title
 63///</summary> 64privatestring value_title = "";
 65 66///<summary> 67/// The left right
 68///</summary> 69privateint leftRight = 50;
 70 71///<summary> 72/// Up dowm
 73///</summary> 74privateint upDowm = 50;
 75 76///<summary> 77/// The data list
 78///</summary> 79private Dictionary<string, CurveItem> data_list = null;
 80 81///<summary> 82/// The data text
 83///</summary> 84privatestring[] data_text = null;
 85 86///<summary> 87/// The auxiliary lines
 88///</summary> 89private List<AuxiliaryLine> auxiliary_lines;
 90 91///<summary> 92/// The auxiliary labels
 93///</summary> 94private List<AuxiliaryLable> auxiliary_Labels;
 95 96///<summary> 97/// The mark texts
 98///</summary> 99private List<MarkText> MarkTexts;
100101///<summary>102/// The font size9
103///</summary>104private Font font_size9 = null;
105106///<summary>107/// The font size12
108///</summary>109private Font font_size12 = null;
110111///<summary>112/// The brush deep
113///</summary>114private Brush brush_deep = null;
115116///<summary>117/// The pen normal
118///</summary>119private Pen pen_normal = null;
120121///<summary>122/// The pen dash
123///</summary>124private Pen pen_dash = null;
125126///<summary>127/// The color normal
128///</summary>129private Color color_normal = Color.DeepPink;
130131///<summary>132/// The color deep
133///</summary>134private Color color_deep = Color.DimGray;
135136///<summary>137/// The color dash
138///</summary>139private Color color_dash = Color.FromArgb(232, 232, 232);
140141///<summary>142/// The color mark font
143///</summary>144private Color color_mark_font = Color.DodgerBlue;
145146///<summary>147/// The brush mark font
148///</summary>149private Brush brush_mark_font = Brushes.DodgerBlue;
150151///<summary>152/// The format left
153///</summary>154private StringFormat format_left = null;
155156///<summary>157/// The format right
158///</summary>159private StringFormat format_right = null;
160161///<summary>162/// The format center
163///</summary>164private StringFormat format_center = null;
165166///<summary>167/// The is render right coordinate
168///</summary>169privatebool isRenderRightCoordinate = true;
170171///<summary>172/// The curve name width
173///</summary>174privateint curveNameWidth = 100;
175176///<summary>177/// The components
178///</summary>179private IContainer components = null;
180181///<summary>182/// 获取或设置控件的背景色。
183///</summary>184///<value>The color of the back.</value>185///<PermissionSet>186///<IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />187///</PermissionSet>188         [Browsable(true)]
189         [Description("获取或设置控件的背景色")]
190         [Category("自定义")]
191         [DefaultValue(typeof(Color), "Transparent")]
192        [EditorBrowsable(EditorBrowsableState.Always)]
193publicoverride Color BackColor
194        {
195get196            {
197returnbase.BackColor;
198            }
199set200            {
201base.BackColor = value;
202            }
203        }
204205///<summary>206/// Gets or sets the value maximum left.
207///</summary>208///<value>The value maximum left.</value>209         [Category("自定义")]
210         [Description("获取或设置图形的左纵坐标的最大值,该值必须大于最小值")]
211         [Browsable(true)]
212        [DefaultValue(100f)]
213publicfloat ValueMaxLeft
214        {
215get216            {
217return value_max_left;
218            }
219set220            {
221                 value_max_left = value;
222                Invalidate();
223            }
224        }
225226///<summary>227/// Gets or sets the value minimum left.
228///</summary>229///<value>The value minimum left.</value>230         [Category("自定义")]
231         [Description("获取或设置图形的左纵坐标的最小值,该值必须小于最大值")]
232         [Browsable(true)]
233        [DefaultValue(0f)]
234publicfloat ValueMinLeft
235        {
236get237            {
238return value_min_left;
239            }
240set241            {
242                 value_min_left = value;
243                Invalidate();
244            }
245        }
246247///<summary>248/// Gets or sets the value maximum right.
249///</summary>250///<value>The value maximum right.</value>251         [Category("自定义")]
252         [Description("获取或设置图形的右纵坐标的最大值,该值必须大于最小值")]
253         [Browsable(true)]
254        [DefaultValue(100f)]
255publicfloat ValueMaxRight
256        {
257get258            {
259return value_max_right;
260            }
261set262            {
263                 value_max_right = value;
264                Invalidate();
265            }
266        }
267268///<summary>269/// Gets or sets the value minimum right.
270///</summary>271///<value>The value minimum right.</value>272         [Category("自定义")]
273         [Description("获取或设置图形的右纵坐标的最小值,该值必须小于最大值")]
274         [Browsable(true)]
275        [DefaultValue(0f)]
276publicfloat ValueMinRight
277        {
278get279            {
280return value_min_right;
281            }
282set283            {
284                 value_min_right = value;
285                Invalidate();
286            }
287        }
288289///<summary>290/// Gets or sets the value segment.
291///</summary>292///<value>The value segment.</value>293         [Category("自定义")]
294         [Description("获取或设置图形的纵轴分段数")]
295         [Browsable(true)]
296         [DefaultValue(5)]
297publicint ValueSegment
298        {
299get300            {
301return value_Segment;
302            }
303set304            {
305                 value_Segment = value;
306                Invalidate();
307            }
308        }
309310///<summary>311/// Gets or sets a value indicating whether this instance is abscissa strech.
312///</summary>313///<value><c>true</c> if this instance is abscissa strech; otherwise, <c>false</c>.</value>314         [Category("自定义")]
315         [Description("获取或设置所有的数据是否强制在一个界面里显示")]
316         [Browsable(true)]
317         [DefaultValue(false)]
318publicbool IsAbscissaStrech
319        {
320get321            {
322return value_IsAbscissaStrech;
323            }
324set325            {
326                 value_IsAbscissaStrech = value;
327                Invalidate();
328            }
329        }
330331///<summary>332/// Gets or sets the strech data count maximum.
333///</summary>334///<value>The strech data count maximum.</value>335         [Category("自定义")]
336         [Description("获取或设置拉伸模式下的最大数据量")]
337         [Browsable(true)]
338         [DefaultValue(300)]
339publicint StrechDataCountMax
340        {
341get342            {
343return value_StrechDataCountMax;
344            }
345set346            {
347                 value_StrechDataCountMax = value;
348                Invalidate();
349            }
350        }
351352///<summary>353/// Gets or sets a value indicating whether this instance is render dash line.
354///</summary>355///<value><c>true</c> if this instance is render dash line; otherwise, <c>false</c>.</value>356         [Category("自定义")]
357         [Description("获取或设置虚线是否进行显示")]
358         [Browsable(true)]
359         [DefaultValue(true)]
360publicbool IsRenderDashLine
361        {
362get363            {
364return value_IsRenderDashLine;
365            }
366set367            {
368                 value_IsRenderDashLine = value;
369                Invalidate();
370            }
371        }
372373///<summary>374/// Gets or sets the color lines and text.
375///</summary>376///<value>The color lines and text.</value>377         [Category("自定义")]
378         [Description("获取或设置坐标轴及相关信息文本的颜色")]
379         [Browsable(true)]
380         [DefaultValue(typeof(Color), "DimGray")]
381public Color ColorLinesAndText
382        {
383get384            {
385return color_deep;
386            }
387set388            {
389                 color_deep = value;
390                InitializationColor();
391                Invalidate();
392            }
393        }
394395///<summary>396/// Gets or sets the color dash lines.
397///</summary>398///<value>The color dash lines.</value>399         [Category("自定义")]
400         [Description("获取或设置虚线的颜色")]
401         [Browsable(true)]
402public Color ColorDashLines
403        {
404get405            {
406return color_dash;
407            }
408set409            {
410                 color_dash = value;
411if (pen_dash != null)
412                    pen_dash.Dispose();
413                 pen_dash = new Pen(color_dash);
414                 pen_dash.DashStyle = DashStyle.Custom;
415                 pen_dash.DashPattern = newfloat[2]
416                {
417                    5f,
418                    5f
419                };
420                Invalidate();
421            }
422        }
423424///<summary>425/// Gets or sets the interval abscissa text.
426///</summary>427///<value>The interval abscissa text.</value>428         [Category("自定义")]
429         [Description("获取或设置纵向虚线的分隔情况,单位为多少个数据")]
430         [Browsable(true)]
431         [DefaultValue(100)]
432publicint IntervalAbscissaText
433        {
434get435            {
436return value_IntervalAbscissaText;
437            }
438set439            {
440                 value_IntervalAbscissaText = value;
441                Invalidate();
442            }
443        }
444445///<summary>446/// Gets or sets the text add format.
447///</summary>448///<value>The text add format.</value>449         [Category("自定义")]
450         [Description("获取或设置实时数据新增时文本相对应于时间的格式化字符串,默认HH:mm")]
451         [Browsable(true)]
452         [DefaultValue("HH:mm")]
453publicstring TextAddFormat
454        {
455get456            {
457return textFormat;
458            }
459set460            {
461                 textFormat = value;
462                Invalidate();
463            }
464        }
465466///<summary>467/// Gets or sets the title.
468///</summary>469///<value>The title.</value>470         [Category("自定义")]
471         [Description("获取或设置图标的标题信息")]
472         [Browsable(true)]
473         [DefaultValue("")]
474publicstring Title
475        {
476get477            {
478return value_title;
479            }
480set481            {
482                 value_title = value;
483                Invalidate();
484            }
485        }
486487///<summary>488/// Gets or sets a value indicating whether this instance is render right coordinate.
489///</summary>490///<value><c>true</c> if this instance is render right coordinate; otherwise, <c>false</c>.</value>491         [Category("自定义")]
492         [Description("获取或设置是否显示右侧的坐标系信息")]
493         [Browsable(true)]
494         [DefaultValue(true)]
495publicbool IsRenderRightCoordinate
496        {
497get498            {
499return isRenderRightCoordinate;
500            }
501set502            {
503                 isRenderRightCoordinate = value;
504                Invalidate();
505            }
506        }
507508///<summary>509/// Gets or sets the width of the curve name.
510///</summary>511///<value>The width of the curve name.</value>512         [Browsable(true)]
513         [Description("获取或设置曲线名称的布局宽度")]
514         [Category("自定义")]
515         [DefaultValue(100)]
516publicint CurveNameWidth
517        {
518get519            {
520return curveNameWidth;
521            }
522set523            {
524if (value > 10)
525                {
526                     curveNameWidth = value;
527                }
528            }
529         }

构造函数做一些初始化

             1
            public
             UCCurve()

             2
                    {

             3
                        InitializeComponent();

             4             random = new Random();
 5             data_list = new Dictionary<string, CurveItem>();
 6             auxiliary_lines = new List<AuxiliaryLine>();
 7             MarkTexts = new List<MarkText>();
 8             auxiliary_Labels = new List<AuxiliaryLable>();
 9             format_left = new StringFormat
10            {
11                 LineAlignment = StringAlignment.Center,
12                 Alignment = StringAlignment.Near
13            };
14             format_right = new StringFormat
15            {
16                 LineAlignment = StringAlignment.Center,
17                 Alignment = StringAlignment.Far
18            };
19             format_center = new StringFormat
20            {
21                 LineAlignment = StringAlignment.Center,
22                 Alignment = StringAlignment.Center
23            };
24             font_size9 = new Font("微软雅黑", 9f);
25             font_size12 = new Font("微软雅黑", 12f);
26            InitializationColor();
27             pen_dash = new Pen(color_deep);
28             pen_dash.DashStyle = DashStyle.Custom;
29             pen_dash.DashPattern = newfloat[2]
30            {
31                5f,
32                5f
33            };
34             SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);
35             SetStyle(ControlStyles.ResizeRedraw, true);
36             SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
37             SetStyle(ControlStyles.AllPaintingInWmPaint, true);
38         }

重绘

              1
            protected
            override
            void
             OnPaint(PaintEventArgs e)

              2
                    {

              3
            try
              4
                        {

              5                 Graphics graphics = e.Graphics;
  6                graphics.SetGDIHigh();
  7if (BackColor != Color.Transparent)
  8                {
  9                    graphics.Clear(BackColor);
 10                }
 11int width = base.Width;
 12int height = base.Height;
 13if (width < 120 || height < 60)
 14                {
 15return;
 16                }
 17                 Point[] array = new Point[4]
 18                {
 19new Point(leftRight - 1, upDowm - 8),
 20new Point(leftRight - 1, height - upDowm),
 21new Point(width - leftRight, height - upDowm),
 22new Point(width - leftRight, upDowm - 8)
 23                };
 24                 graphics.DrawLine(pen_normal, array[0], array[1]);
 25                 graphics.DrawLine(pen_normal, array[1], array[2]);
 26if (isRenderRightCoordinate)
 27                {
 28                     graphics.DrawLine(pen_normal, array[2], array[3]);
 29                }
 30 31if (!string.IsNullOrEmpty(value_title))
 32                {
 33                     graphics.DrawString(value_title, font_size9, brush_deep, new Rectangle(0, 0, width - 1, 20), format_center);
 34                }
 35 36if (data_list.Count > 0)
 37                {
 38float num = leftRight + 10;
 39foreach (KeyValuePair<string, CurveItem> item in data_list)
 40                    {
 41if (item.Value.Visible)
 42                        {
 43var titleSize=graphics.MeasureString(item.Key, Font);
 44                             SolidBrush solidBrush = item.Value.LineRenderVisiable ? new SolidBrush(item.Value.LineColor) : new SolidBrush(Color.FromArgb(80, item.Value.LineColor));
 45                             graphics.FillRectangle(solidBrush, num + 8f, 24f, 20f, 14f);
 46                             graphics.DrawString(item.Key, Font, solidBrush, new PointF(num + 30f, 24f+(14 - titleSize.Height) / 2));
 47                             item.Value.TitleRegion = new RectangleF(num, 24f, 60f, 18f);
 48                            solidBrush.Dispose();
 49                             num += titleSize.Width + 30;
 50                        }
 51                    }
 52                }
 53 54 55for (int i = 0; i < auxiliary_Labels.Count; i++)
 56                {
 57if (!string.IsNullOrEmpty(auxiliary_Labels[i].Text))
 58                    {
 59int num2 = (auxiliary_Labels[i].LocationX > 1f) ? ((int)auxiliary_Labels[i].LocationX) : ((int)(auxiliary_Labels[i].LocationX * (float)width));
 60int num3 = (int)graphics.MeasureString(auxiliary_Labels[i].Text, Font).Width + 3;
 61                         Point[] points = new Point[6]
 62                    {
 63new Point(num2, 11),
 64new Point(num2 + 10, 20),
 65new Point(num2 + num3 + 10, 20),
 66new Point(num2 + num3 + 10, 0),
 67new Point(num2 + 10, 0),
 68new Point(num2, 11)
 69                    };
 70                        graphics.FillPolygon(auxiliary_Labels[i].TextBack, points);
 71                         graphics.DrawString(auxiliary_Labels[i].Text, Font, auxiliary_Labels[i].TextBrush, new Rectangle(num2 + 7, 0, num3 + 3, 20), format_center);
 72                    }
 73                }
 74                 ControlHelper.PaintTriangle(graphics, brush_deep, new Point(leftRight - 1, upDowm - 8), 4, GraphDirection.Upward);
 75if (isRenderRightCoordinate)
 76                {
 77                     ControlHelper.PaintTriangle(graphics, brush_deep, new Point(width - leftRight, upDowm - 8), 4, GraphDirection.Upward);
 78                }
 79for (int j = 0; j < auxiliary_lines.Count; j++)
 80                {
 81if (auxiliary_lines[j].IsLeftFrame)
 82                    {
 83                         auxiliary_lines[j].PaintValue = ControlHelper.ComputePaintLocationY(value_max_left, value_min_left, height - upDowm - upDowm, auxiliary_lines[j].Value) + (float)upDowm;
 84                    }
 85else 86                    {
 87                         auxiliary_lines[j].PaintValue = ControlHelper.ComputePaintLocationY(value_max_right, value_min_right, height - upDowm - upDowm, auxiliary_lines[j].Value) + (float)upDowm;
 88                    }
 89                }
 90for (int k = 0; k <= value_Segment; k++)
 91                {
 92float value = (float)((double)k * (double)(value_max_left - value_min_left) / (double)value_Segment + (double)value_min_left);
 93float num4 = ControlHelper.ComputePaintLocationY(value_max_left, value_min_left, height - upDowm - upDowm, value) + (float)upDowm;
 94if (IsNeedPaintDash(num4))
 95                    {
 96                         graphics.DrawLine(pen_normal, leftRight - 4, num4, leftRight - 1, num4);
 97                         RectangleF layoutRectangle = new RectangleF(0f, num4 - 9f, leftRight - 4, 20f);
 98                        graphics.DrawString(value.ToString(), font_size9, brush_deep, layoutRectangle, format_right);
 99if (isRenderRightCoordinate)
100                        {
101float num5 = (float)k * (value_max_right - value_min_right) / (float)value_Segment + value_min_right;
102                             graphics.DrawLine(pen_normal, width - leftRight + 1, num4, width - leftRight + 4, num4);
103                             layoutRectangle.Location = new PointF(width - leftRight + 4, num4 - 9f);
104                            graphics.DrawString(num5.ToString(), font_size9, brush_deep, layoutRectangle, format_left);
105                        }
106if (k > 0 && value_IsRenderDashLine)
107                        {
108                             graphics.DrawLine(pen_dash, leftRight, num4, width - leftRight, num4);
109                        }
110                    }
111                }
112if (value_IsRenderDashLine)
113                {
114if (value_IsAbscissaStrech)
115                    {
116float num6 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
117int num7 = CalculateDataCountByOffect(num6);
118for (int l = 0; l < value_StrechDataCountMax; l += num7)
119                        {
120if (l > 0 && l < value_StrechDataCountMax - 1)
121                            {
122                                 graphics.DrawLine(pen_dash, (float)l * num6 + (float)leftRight, upDowm, (float)l * num6 + (float)leftRight, height - upDowm - 1);
123                            }
124if (data_text != null && l < data_text.Length && (float)l * num6 + (float)leftRight < (float)(data_text.Length - 1) * num6 + (float)leftRight - 40f)
125                            {
126                                 graphics.DrawString(layoutRectangle: new Rectangle((int)((float)l * num6), height - upDowm + 1, leftRight * 2, upDowm), s: data_text[l], font: font_size9, brush: brush_deep, format: format_center);
127                            }
128                        }
129string[] array2 = data_text;
130if (array2 != null && array2.Length > 1)
131                        {
132if (data_text.Length < value_StrechDataCountMax)
133                            {
134                                 graphics.DrawLine(pen_dash, (float)(data_text.Length - 1) * num6 + (float)leftRight, upDowm, (float)(data_text.Length - 1) * num6 + (float)leftRight, height - upDowm - 1);
135                            }
136                             graphics.DrawString(layoutRectangle: new Rectangle((int)((float)(data_text.Length - 1) * num6 + (float)leftRight) - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[data_text.Length - 1], font: font_size9, brush: brush_deep, format: format_center);
137                        }
138                    }
139elseif (value_IntervalAbscissaText > 0)
140                    {
141int num8 = width - 2 * leftRight + 1;
142for (int m = leftRight; m < width - leftRight; m += value_IntervalAbscissaText)
143                        {
144if (m != leftRight)
145                            {
146                                 graphics.DrawLine(pen_dash, m, upDowm, m, height - upDowm - 1);
147                            }
148if (data_text == null)
149                            {
150continue;
151                            }
152int num9 = (num8 > data_text.Length) ? data_text.Length : num8;
153if (m - leftRight < data_text.Length && num9 - (m - leftRight) > 40)
154                            {
155if (data_text.Length <= num8)
156                                {
157                                     graphics.DrawString(layoutRectangle: new Rectangle(m - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[m - leftRight], font: font_size9, brush: brush_deep, format: format_center);
158                                }
159else160                                {
161                                     graphics.DrawString(layoutRectangle: new Rectangle(m - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[m - leftRight + data_text.Length - num8], font: font_size9, brush: brush_deep, format: format_center);
162                                }
163                            }
164                        }
165string[] array3 = data_text;
166if (array3 != null && array3.Length > 1)
167                        {
168if (data_text.Length >= num8)
169                            {
170                                 graphics.DrawString(layoutRectangle: new Rectangle(width - leftRight - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[data_text.Length - 1], font: font_size9, brush: brush_deep, format: format_center);
171                            }
172else173                            {
174                                 graphics.DrawLine(pen_dash, data_text.Length + leftRight - 1, upDowm, data_text.Length + leftRight - 1, height - upDowm - 1);
175                                 graphics.DrawString(layoutRectangle: new Rectangle(data_text.Length + leftRight - 1 - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[data_text.Length - 1], font: font_size9, brush: brush_deep, format: format_center);
176                            }
177                        }
178                    }
179                }
180for (int n = 0; n < auxiliary_lines.Count; n++)
181                {
182if (auxiliary_lines[n].IsLeftFrame)
183                    {
184                         graphics.DrawLine(auxiliary_lines[n].GetPen(), leftRight - 4, auxiliary_lines[n].PaintValue, leftRight - 1, auxiliary_lines[n].PaintValue);
185                         graphics.DrawString(layoutRectangle: new RectangleF(0f, auxiliary_lines[n].PaintValue - 9f, leftRight - 4, 20f), s: auxiliary_lines[n].Value.ToString(), font: font_size9, brush: auxiliary_lines[n].LineTextBrush, format: format_right);
186                    }
187else188                    {
189                         graphics.DrawLine(auxiliary_lines[n].GetPen(), width - leftRight + 1, auxiliary_lines[n].PaintValue, width - leftRight + 4, auxiliary_lines[n].PaintValue);
190                         graphics.DrawString(layoutRectangle: new RectangleF(width - leftRight + 4, auxiliary_lines[n].PaintValue - 9f, leftRight - 4, 20f), s: auxiliary_lines[n].Value.ToString(), font: font_size9, brush: auxiliary_lines[n].LineTextBrush, format: format_left);
191                    }
192                     graphics.DrawLine(auxiliary_lines[n].GetPen(), leftRight, auxiliary_lines[n].PaintValue, width - leftRight, auxiliary_lines[n].PaintValue);
193                }
194if (value_IsAbscissaStrech)
195                {
196foreach (MarkText MarkText in MarkTexts)
197                    {
198foreach (KeyValuePair<string, CurveItem> item2 in data_list)
199                        {
200if (item2.Value.Visible && item2.Value.LineRenderVisiable && !(item2.Key != MarkText.CurveKey))
201                            {
202float[] data = item2.Value.Data;
203if (data != null && data.Length > 1)
204                                {
205float num10 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
206if (MarkText.Index >= 0 && MarkText.Index < item2.Value.Data.Length)
207                                    {
208                                         PointF pointF = new PointF((float)leftRight + (float)MarkText.Index * num10, ControlHelper.ComputePaintLocationY(item2.Value.IsLeftFrame ? value_max_left : value_max_right, item2.Value.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, item2.Value.Data[MarkText.Index]) + (float)upDowm);
209                                         graphics.FillEllipse(new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X - 3f, pointF.Y - 3f, 6f, 6f));
210switch ((MarkText.PositionStyle == MarkTextPositionStyle.Auto) ? MarkText.CalculateDirectionFromDataIndex(item2.Value.Data, MarkText.Index) : MarkText.PositionStyle)
211                                        {
212case MarkTextPositionStyle.Left:
213                                                 graphics.DrawString(MarkText.Text, Font, new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X - 100f, pointF.Y - (float)Font.Height, 100 - MarkText.MarkTextOffect, Font.Height * 2), format_right);
214break;
215case MarkTextPositionStyle.Up:
216                                                 graphics.DrawString(MarkText.Text, Font, new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X - 100f, pointF.Y - (float)Font.Height - (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
217break;
218case MarkTextPositionStyle.Right:
219                                                 graphics.DrawString(MarkText.Text, Font, new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X + (float)MarkText.MarkTextOffect, pointF.Y - (float)Font.Height, 100f, Font.Height * 2), format_left);
220break;
221case MarkTextPositionStyle.Down:
222                                                 graphics.DrawString(MarkText.Text, Font, new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X - 100f, pointF.Y + (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
223break;
224                                        }
225                                    }
226                                }
227                            }
228                        }
229                    }
230foreach (CurveItem value2 in data_list.Values)
231                    {
232if (value2.Visible && value2.LineRenderVisiable)
233                        {
234float[] data2 = value2.Data;
235if (data2 != null && data2.Length > 1)
236                            {
237float num11 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
238                                 PointF[] array4 = new PointF[value2.Data.Length];
239for (int num12 = 0; num12 < value2.Data.Length; num12++)
240                                {
241                                     array4[num12].X = (float)leftRight + (float)num12 * num11;
242                                     array4[num12].Y = ControlHelper.ComputePaintLocationY(value2.IsLeftFrame ? value_max_left : value_max_right, value2.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, value2.Data[num12]) + (float)upDowm;
243if (!string.IsNullOrEmpty(value2.MarkText[num12]))
244                                    {
245using (Brush brush = new SolidBrush(value2.LineColor))
246                                        {
247                                             graphics.FillEllipse(brush, new RectangleF(array4[num12].X - 3f, array4[num12].Y - 3f, 6f, 6f));
248switch (MarkText.CalculateDirectionFromDataIndex(value2.Data, num12))
249                                            {
250case MarkTextPositionStyle.Left:
251                                                     graphics.DrawString(value2.MarkText[num12], Font, brush, new RectangleF(array4[num12].X - 100f, array4[num12].Y - (float)Font.Height, 100 - MarkText.MarkTextOffect, Font.Height * 2), format_right);
252break;
253case MarkTextPositionStyle.Up:
254                                                     graphics.DrawString(value2.MarkText[num12], Font, brush, new RectangleF(array4[num12].X - 100f, array4[num12].Y - (float)Font.Height - (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
255break;
256case MarkTextPositionStyle.Right:
257                                                     graphics.DrawString(value2.MarkText[num12], Font, brush, new RectangleF(array4[num12].X + (float)MarkText.MarkTextOffect, array4[num12].Y - (float)Font.Height, 100f, Font.Height * 2), format_left);
258break;
259case MarkTextPositionStyle.Down:
260                                                     graphics.DrawString(value2.MarkText[num12], Font, brush, new RectangleF(array4[num12].X - 100f, array4[num12].Y + (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
261break;
262                                            }
263                                        }
264                                    }
265                                }
266using (Pen pen2 = new Pen(value2.LineColor, value2.LineThickness))
267                                {
268if (value2.IsSmoothCurve)
269                                    {
270                                        graphics.DrawCurve(pen2, array4);
271                                    }
272else273                                    {
274                                        graphics.DrawLines(pen2, array4);
275                                    }
276                                }
277                            }
278                        }
279                    }
280                }
281else282                {
283foreach (MarkText MarkText2 in MarkTexts)
284                    {
285foreach (KeyValuePair<string, CurveItem> item3 in data_list)
286                        {
287if (item3.Value.Visible && item3.Value.LineRenderVisiable && !(item3.Key != MarkText2.CurveKey))
288                            {
289float[] data3 = item3.Value.Data;
290if (data3 != null && data3.Length > 1 && MarkText2.Index >= 0 && MarkText2.Index < item3.Value.Data.Length)
291                                {
292                                     PointF pointF2 = new PointF(leftRight + MarkText2.Index, ControlHelper.ComputePaintLocationY(item3.Value.IsLeftFrame ? value_max_left : value_max_right, item3.Value.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, item3.Value.Data[MarkText2.Index]) + (float)upDowm);
293                                     graphics.FillEllipse(new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X - 3f, pointF2.Y - 3f, 6f, 6f));
294switch ((MarkText2.PositionStyle == MarkTextPositionStyle.Auto) ? MarkText.CalculateDirectionFromDataIndex(item3.Value.Data, MarkText2.Index) : MarkText2.PositionStyle)
295                                    {
296case MarkTextPositionStyle.Left:
297                                             graphics.DrawString(MarkText2.Text, Font, new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X - 100f, pointF2.Y - (float)Font.Height, 100 - MarkText.MarkTextOffect, Font.Height * 2), format_right);
298break;
299case MarkTextPositionStyle.Up:
300                                             graphics.DrawString(MarkText2.Text, Font, new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X - 100f, pointF2.Y - (float)Font.Height - (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
301break;
302case MarkTextPositionStyle.Right:
303                                             graphics.DrawString(MarkText2.Text, Font, new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X + (float)MarkText.MarkTextOffect, pointF2.Y - (float)Font.Height, 100f, Font.Height * 2), format_left);
304break;
305case MarkTextPositionStyle.Down:
306                                             graphics.DrawString(MarkText2.Text, Font, new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X - 100f, pointF2.Y + (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
307break;
308                                    }
309                                }
310                            }
311                        }
312                    }
313foreach (CurveItem value3 in data_list.Values)
314                    {
315if (value3.Visible && value3.LineRenderVisiable)
316                        {
317float[] data4 = value3.Data;
318if (data4 != null && data4.Length > 1)
319                            {
320int num13 = width - 2 * leftRight + 1;
321                                PointF[] array5;
322if (value3.Data.Length <= num13)
323                                {
324                                     array5 = new PointF[value3.Data.Length];
325for (int num14 = 0; num14 < value3.Data.Length; num14++)
326                                    {
327                                         array5[num14].X = leftRight + num14;
328                                         array5[num14].Y = ControlHelper.ComputePaintLocationY(value3.IsLeftFrame ? value_max_left : value_max_right, value3.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, value3.Data[num14]) + (float)upDowm;
329                                        DrawMarkPoint(graphics, value3.MarkText[num14], array5[num14], value3.LineColor, MarkText.CalculateDirectionFromDataIndex(value3.Data, num14));
330                                    }
331                                }
332else333                                {
334                                     array5 = new PointF[num13];
335for (int num15 = 0; num15 < array5.Length; num15++)
336                                    {
337int num16 = num15 + value3.Data.Length - num13;
338                                         array5[num15].X = leftRight + num15;
339                                         array5[num15].Y = ControlHelper.ComputePaintLocationY(value3.IsLeftFrame ? value_max_left : value_max_right, value3.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, value3.Data[num16]) + (float)upDowm;
340                                        DrawMarkPoint(graphics, value3.MarkText[num16], array5[num15], value3.LineColor, MarkText.CalculateDirectionFromDataIndex(value3.Data, num16));
341                                    }
342                                }
343using (Pen pen3 = new Pen(value3.LineColor, value3.LineThickness))
344                                {
345if (value3.IsSmoothCurve)
346                                    {
347                                        graphics.DrawCurve(pen3, array5);
348                                    }
349else350                                    {
351                                        graphics.DrawLines(pen3, array5);
352                                    }
353                                }
354                            }
355                        }
356                    }
357                }
358base.OnPaint(e);
359            }
360catch (Exception exc)
361            {
362                 e.Graphics.DrawString(exc.Message, this.Font, Brushes.Black, 10, 10);
363            }
364         }

辅助函数

             1
            ///
            <summary>
             2
            ///
             Draws the mark point.

             3
            ///
            </summary>
             4
            ///
            <param name="g">
            The g.
            </param>
             5
            ///
            <param name="markText">
            The mark text.
            </param>
             6
            ///
            <param name="center">
            The center.
            </param>
             7
            ///
            <param name="color">
            The color.
            </param>
             8
            ///
            <param name="markTextPosition">
            The mark text position.
            </param>
             9
            private
            void DrawMarkPoint(Graphics g, string markText, PointF center, Color color, MarkTextPositionStyle markTextPosition)
10        {
11if (!string.IsNullOrEmpty(markText))
12            {
13using (Brush brush = new SolidBrush(color))
14                {
15                    DrawMarkPoint(g, markText, center, brush, markTextPosition);
16                }
17            }
18        }
1920///<summary>21/// Draws the mark point.
22///</summary>23///<param name="g">The g.</param>24///<param name="markText">The mark text.</param>25///<param name="center">The center.</param>26///<param name="brush">The brush.</param>27///<param name="markTextPosition">The mark text position.</param>28privatevoid DrawMarkPoint(Graphics g, string markText, PointF center, Brush brush, MarkTextPositionStyle markTextPosition)
29        {
30if (!string.IsNullOrEmpty(markText))
31            {
32                 g.FillEllipse(brush, new RectangleF(center.X - 3f, center.Y - 3f, 6f, 6f));
33switch (markTextPosition)
34                {
35case MarkTextPositionStyle.Left:
36                         g.DrawString(markText, Font, brush, new RectangleF(center.X - 100f, center.Y - (float)Font.Height, 100 - MarkText.MarkTextOffect, Font.Height * 2), format_right);
37break;
38case MarkTextPositionStyle.Up:
39                         g.DrawString(markText, Font, brush, new RectangleF(center.X - 100f, center.Y - (float)Font.Height - (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
40break;
41case MarkTextPositionStyle.Right:
42                         g.DrawString(markText, Font, brush, new RectangleF(center.X + (float)MarkText.MarkTextOffect, center.Y - (float)Font.Height, 100f, Font.Height * 2), format_left);
43break;
44case MarkTextPositionStyle.Down:
45                         g.DrawString(markText, Font, brush, new RectangleF(center.X - 100f, center.Y + (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
46break;
47                }
48            }
49        }
5051///<summary>52/// Determines whether [is need paint dash] [the specified paint value].
53///</summary>54///<param name="paintValue">The paint value.</param>55///<returns><c>true</c> if [is need paint dash] [the specified paint value]; otherwise, <c>false</c>.</returns>56privatebool IsNeedPaintDash(float paintValue)
57        {
58for (int i = 0; i < auxiliary_lines.Count; i++)
59            {
60if (Math.Abs(auxiliary_lines[i].PaintValue - paintValue) < (float)font_size9.Height)
61                {
62returnfalse;
63                }
64            }
65returntrue;
66        }
6768///<summary>69/// Calculates the data count by offect.
70///</summary>71///<param name="offect">The offect.</param>72///<returns>System.Int32.</returns>73privateint CalculateDataCountByOffect(float offect)
74        {
75if (value_IntervalAbscissaText > 0)
76            {
77return value_IntervalAbscissaText;
78            }
79if (offect > 40f)
80            {
81return1;
82            }
83             offect = 40f / offect;
84return (int)Math.Ceiling(offect);
85         }

一些公开函数

              1
            ///
            <summary>
              2
            ///
             Sets the curve text.

              3
            ///
            </summary>
              4
            ///
            <param name="descriptions">
            The descriptions.
            </param>
              5
            public
            void SetCurveText(string[] descriptions)
  6        {
  7             data_text = descriptions;
  8            Invalidate();
  9        }
 10 11///<summary> 12/// Sets the left curve.
 13///</summary> 14///<param name="key">The key.</param> 15///<param name="data">The data.</param> 16///<param name="lineColor">Color of the line.</param> 17publicvoid SetLeftCurve(string key, float[] data, Color? lineColor = null)
 18        {
 19             SetCurve(key, true, data, lineColor, 1f, false);
 20        }
 21 22///<summary> 23/// Sets the left curve.
 24///</summary> 25///<param name="key">The key.</param> 26///<param name="data">The data.</param> 27///<param name="lineColor">Color of the line.</param> 28///<param name="isSmooth">if set to <c>true</c> [is smooth].</param> 29publicvoid SetLeftCurve(string key, float[] data, Color? lineColor, bool isSmooth = false)
 30        {
 31             SetCurve(key, true, data, lineColor, 1f, isSmooth);
 32        }
 33 34///<summary> 35/// Sets the right curve.
 36///</summary> 37///<param name="key">The key.</param> 38///<param name="data">The data.</param> 39///<param name="lineColor">Color of the line.</param> 40publicvoid SetRightCurve(string key, float[] data, Color? lineColor = null)
 41        {
 42             SetCurve(key, false, data, lineColor, 1f, false);
 43        }
 44 45///<summary> 46/// Sets the right curve.
 47///</summary> 48///<param name="key">The key.</param> 49///<param name="data">The data.</param> 50///<param name="lineColor">Color of the line.</param> 51///<param name="isSmooth">if set to <c>true</c> [is smooth].</param> 52publicvoid SetRightCurve(string key, float[] data, Color? lineColor, bool isSmooth = false)
 53        {
 54             SetCurve(key, false, data, lineColor, 1f, isSmooth);
 55        }
 56 57///<summary> 58/// Sets the curve.
 59///</summary> 60///<param name="key">The key.</param> 61///<param name="isLeft">if set to <c>true</c> [is left].</param> 62///<param name="data">The data.</param> 63///<param name="lineColor">Color of the line.</param> 64///<param name="thickness">The thickness.</param> 65///<param name="isSmooth">if set to <c>true</c> [is smooth].</param> 66publicvoid SetCurve(string key, bool isLeft, float[] data, Color? lineColor, float thickness, bool isSmooth)
 67        {
 68if (data_list.ContainsKey(key))
 69            {
 70if (data == null)
 71                {
 72                     data = newfloat[0];
 73                }
 74                 data_list[key].Data = data;
 75            }
 76else 77            {
 78if (data == null)
 79                {
 80                     data = newfloat[0];
 81                }
 82                 data_list.Add(key, new CurveItem
 83                {
 84                     Data = data,
 85                     MarkText = newstring[data.Length],
 86                     LineThickness = thickness,
 87                     LineColor = lineColor ?? ControlHelper.Colors[data_list.Count + 13],
 88                     IsLeftFrame = isLeft,
 89                     IsSmoothCurve = isSmooth
 90                });
 91if (data_text == null)
 92                {
 93                     data_text = newstring[data.Length];
 94                }
 95            }
 96            Invalidate();
 97        }
 98 99///<summary>100/// Removes the curve.
101///</summary>102///<param name="key">The key.</param>103publicvoid RemoveCurve(string key)
104        {
105if (data_list.ContainsKey(key))
106            {
107                data_list.Remove(key);
108            }
109if (data_list.Count == 0)
110            {
111                 data_text = newstring[0];
112            }
113            Invalidate();
114        }
115116///<summary>117/// Removes all curve.
118///</summary>119publicvoid RemoveAllCurve()
120        {
121int count = data_list.Count;
122            data_list.Clear();
123if (data_list.Count == 0)
124            {
125                 data_text = newstring[0];
126            }
127if (count > 0)
128            {
129                Invalidate();
130            }
131        }
132133///<summary>134/// Removes all curve data.
135///</summary>136publicvoid RemoveAllCurveData()
137        {
138int count = data_list.Count;
139foreach (KeyValuePair<string, CurveItem> item in data_list)
140            {
141                 item.Value.Data = newfloat[0];
142                 item.Value.MarkText = newstring[0];
143            }
144             data_text = newstring[0];
145if (count > 0)
146            {
147                Invalidate();
148            }
149        }
150151///<summary>152/// Gets the curve item.
153///</summary>154///<param name="key">The key.</param>155///<returns>CurveItem.</returns>156public CurveItem GetCurveItem(string key)
157        {
158if (data_list.ContainsKey(key))
159            {
160return data_list[key];
161            }
162returnnull;
163        }
164165///<summary>166/// Saves to bitmap.
167///</summary>168///<returns>Bitmap.</returns>169public Bitmap SaveToBitmap()
170        {
171return SaveToBitmap(base.Width, base.Height);
172        }
173174///<summary>175/// Saves to bitmap.
176///</summary>177///<param name="width">The width.</param>178///<param name="height">The height.</param>179///<returns>Bitmap.</returns>180public Bitmap SaveToBitmap(int width, int height)
181        {
182             Bitmap bitmap = new Bitmap(width, height);
183             Graphics graphics = Graphics.FromImage(bitmap);
184             OnPaint(new PaintEventArgs(graphics, new Rectangle(0, 0, width, height)));
185return bitmap;
186        }
187188///<summary>189/// Adds the curve data.
190///</summary>191///<param name="key">The key.</param>192///<param name="values">The values.</param>193///<param name="markTexts">The mark texts.</param>194///<param name="isUpdateUI">if set to <c>true</c> [is update UI].</param>195privatevoid AddCurveData(string key, float[] values, string[] markTexts, bool isUpdateUI)
196        {
197if ((values != null && values.Length < 1) || !data_list.ContainsKey(key))
198            {
199return;
200            }
201             CurveItem CurveItem = data_list[key];
202if (CurveItem.Data != null)
203            {
204if (value_IsAbscissaStrech)
205                {
206                     ControlHelper.AddArrayData(ref CurveItem.Data, values, value_StrechDataCountMax);
207                     ControlHelper.AddArrayData(ref CurveItem.MarkText, markTexts, value_StrechDataCountMax);
208                }
209else210                {
211                     ControlHelper.AddArrayData(ref CurveItem.Data, values, 4096);
212                     ControlHelper.AddArrayData(ref CurveItem.MarkText, markTexts, 4096);
213                }
214if (isUpdateUI)
215                {
216                    Invalidate();
217                }
218            }
219        }
220221///<summary>222/// Adds the curve time.
223///</summary>224///<param name="count">The count.</param>225privatevoid AddCurveTime(int count)
226        {
227            AddCurveTime(count, DateTime.Now.ToString(textFormat));
228        }
229230///<summary>231/// Adds the curve time.
232///</summary>233///<param name="count">The count.</param>234///<param name="text">The text.</param>235privatevoid AddCurveTime(int count, string text)
236        {
237if (data_text != null)
238            {
239string[] array = newstring[count];
240for (int i = 0; i < array.Length; i++)
241                {
242                     array[i] = text;
243                }
244if (value_IsAbscissaStrech)
245                {
246                     ControlHelper.AddArrayData(ref data_text, array, value_StrechDataCountMax);
247                }
248else249                {
250                     ControlHelper.AddArrayData(ref data_text, array, 4096);
251                }
252            }
253        }
254255///<summary>256/// Adds the curve data.
257///</summary>258///<param name="key">The key.</param>259///<param name="value">The value.</param>260publicvoid AddCurveData(string key, float value)
261        {
262             AddCurveData(key, newfloat[1]
263            {
264                value
265            });
266        }
267268///<summary>269/// Adds the curve data.
270///</summary>271///<param name="key">The key.</param>272///<param name="value">The value.</param>273///<param name="markText">The mark text.</param>274publicvoid AddCurveData(string key, float value, string markText)
275        {
276             AddCurveData(key, newfloat[1]
277            {
278                value
279             }, newstring[1]
280            {
281                markText
282            });
283        }
284285///<summary>286/// Adds the curve data.
287///</summary>288///<param name="key">The key.</param>289///<param name="values">The values.</param>290publicvoid AddCurveData(string key, float[] values)
291        {
292             AddCurveData(key, values, null);
293        }
294295///<summary>296/// Adds the curve data.
297///</summary>298///<param name="key">The key.</param>299///<param name="values">The values.</param>300///<param name="markTexts">The mark texts.</param>301publicvoid AddCurveData(string key, float[] values, string[] markTexts)
302        {
303if (markTexts == null)
304            {
305                 markTexts = newstring[values.Length];
306            }
307             AddCurveData(key, values, markTexts, false);
308if (values != null && values.Length != 0)
309            {
310                AddCurveTime(values.Length);
311            }
312            Invalidate();
313        }
314315///<summary>316/// Adds the curve data.
317///</summary>318///<param name="keys">The keys.</param>319///<param name="values">The values.</param>320publicvoid AddCurveData(string[] keys, float[] values)
321        {
322             AddCurveData(keys, values, null);
323        }
324325///<summary>326/// Adds the curve data.
327///</summary>328///<param name="axisText">The axis text.</param>329///<param name="keys">The keys.</param>330///<param name="values">The values.</param>331publicvoid AddCurveData(string axisText, string[] keys, float[] values)
332        {
333             AddCurveData(axisText, keys, values, null);
334        }
335336///<summary>337/// Adds the curve data.
338///</summary>339///<param name="keys">The keys.</param>340///<param name="values">The values.</param>341///<param name="markTexts">The mark texts.</param>342///<exception cref="ArgumentNullException">keys
343/// or
344/// values</exception>345///<exception cref="Exception">两个参数的数组长度不一致。
346/// or
347/// 两个参数的数组长度不一致。</exception>348publicvoid AddCurveData(string[] keys, float[] values, string[] markTexts)
349        {
350if (keys == null)
351            {
352thrownew ArgumentNullException("keys");
353            }
354if (values == null)
355            {
356thrownew ArgumentNullException("values");
357            }
358if (markTexts == null)
359            {
360                 markTexts = newstring[keys.Length];
361            }
362if (keys.Length != values.Length)
363            {
364thrownew Exception("两个参数的数组长度不一致。");
365            }
366if (keys.Length != markTexts.Length)
367            {
368thrownew Exception("两个参数的数组长度不一致。");
369            }
370for (int i = 0; i < keys.Length; i++)
371            {
372                 AddCurveData(keys[i], newfloat[1]
373                {
374                    values[i]
375                 }, newstring[1]
376                {
377                    markTexts[i]
378                 }, false);
379            }
380             AddCurveTime(1);
381            Invalidate();
382        }
383384///<summary>385/// Adds the curve data.
386///</summary>387///<param name="axisText">The axis text.</param>388///<param name="keys">The keys.</param>389///<param name="values">The values.</param>390///<param name="markTexts">The mark texts.</param>391///<exception cref="ArgumentNullException">keys
392/// or
393/// values</exception>394///<exception cref="Exception">两个参数的数组长度不一致。
395/// or
396/// 两个参数的数组长度不一致。</exception>397publicvoid AddCurveData(string axisText, string[] keys, float[] values, string[] markTexts)
398        {
399if (keys == null)
400            {
401thrownew ArgumentNullException("keys");
402            }
403if (values == null)
404            {
405thrownew ArgumentNullException("values");
406            }
407if (markTexts == null)
408            {
409                 markTexts = newstring[keys.Length];
410            }
411if (keys.Length != values.Length)
412            {
413thrownew Exception("两个参数的数组长度不一致。");
414            }
415if (keys.Length != markTexts.Length)
416            {
417thrownew Exception("两个参数的数组长度不一致。");
418            }
419for (int i = 0; i < keys.Length; i++)
420            {
421                 AddCurveData(keys[i], newfloat[1]
422                {
423                    values[i]
424                 }, newstring[1]
425                {
426                    markTexts[i]
427                 }, false);
428            }
429             AddCurveTime(1, axisText);
430            Invalidate();
431        }
432433///<summary>434/// Sets the curve visible.
435///</summary>436///<param name="key">The key.</param>437///<param name="visible">if set to <c>true</c> [visible].</param>438publicvoid SetCurveVisible(string key, bool visible)
439        {
440if (data_list.ContainsKey(key))
441            {
442                 CurveItem CurveItem = data_list[key];
443                 CurveItem.Visible = visible;
444                Invalidate();
445            }
446        }
447448///<summary>449/// Sets the curve visible.
450///</summary>451///<param name="keys">The keys.</param>452///<param name="visible">if set to <c>true</c> [visible].</param>453publicvoid SetCurveVisible(string[] keys, bool visible)
454        {
455foreach (string key in keys)
456            {
457if (data_list.ContainsKey(key))
458                {
459                     CurveItem CurveItem = data_list[key];
460                     CurveItem.Visible = visible;
461                }
462            }
463            Invalidate();
464        }
465466///<summary>467/// Adds the left auxiliary.
468///</summary>469///<param name="value">The value.</param>470publicvoid AddLeftAuxiliary(float value)
471        {
472            AddLeftAuxiliary(value, ColorLinesAndText);
473        }
474475///<summary>476/// Adds the left auxiliary.
477///</summary>478///<param name="value">The value.</param>479///<param name="lineColor">Color of the line.</param>480publicvoid AddLeftAuxiliary(float value, Color lineColor)
481        {
482             AddLeftAuxiliary(value, lineColor, 1f, true);
483        }
484485///<summary>486/// Adds the left auxiliary.
487///</summary>488///<param name="value">The value.</param>489///<param name="lineColor">Color of the line.</param>490///<param name="lineThickness">The line thickness.</param>491///<param name="isDashLine">if set to <c>true</c> [is dash line].</param>492publicvoid AddLeftAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine)
493        {
494             AddAuxiliary(value, lineColor, lineThickness, isDashLine, true);
495        }
496497///<summary>498/// Adds the right auxiliary.
499///</summary>500///<param name="value">The value.</param>501publicvoid AddRightAuxiliary(float value)
502        {
503            AddRightAuxiliary(value, ColorLinesAndText);
504        }
505506///<summary>507/// Adds the right auxiliary.
508///</summary>509///<param name="value">The value.</param>510///<param name="lineColor">Color of the line.</param>511publicvoid AddRightAuxiliary(float value, Color lineColor)
512        {
513             AddRightAuxiliary(value, lineColor, 1f, true);
514        }
515516///<summary>517/// Adds the right auxiliary.
518///</summary>519///<param name="value">The value.</param>520///<param name="lineColor">Color of the line.</param>521///<param name="lineThickness">The line thickness.</param>522///<param name="isDashLine">if set to <c>true</c> [is dash line].</param>523publicvoid AddRightAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine)
524        {
525             AddAuxiliary(value, lineColor, lineThickness, isDashLine, false);
526        }
527528///<summary>529/// Adds the auxiliary.
530///</summary>531///<param name="value">The value.</param>532///<param name="lineColor">Color of the line.</param>533///<param name="lineThickness">The line thickness.</param>534///<param name="isDashLine">if set to <c>true</c> [is dash line].</param>535///<param name="isLeft">if set to <c>true</c> [is left].</param>536privatevoid AddAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine, bool isLeft)
537        {
538             auxiliary_lines.Add(new AuxiliaryLine
539            {
540                 Value = value,
541                 LineColor = lineColor,
542                 PenDash = new Pen(lineColor)
543                {
544                     DashStyle = DashStyle.Custom,
545                     DashPattern = newfloat[2]
546                    {
547                        5f,
548                        5f
549                    }
550                },
551                 PenSolid = new Pen(lineColor),
552                 IsDashStyle = isDashLine,
553                 IsLeftFrame = isLeft,
554                 LineThickness = lineThickness,
555                 LineTextBrush = new SolidBrush(lineColor)
556            });
557            Invalidate();
558        }
559560///<summary>561/// Removes the auxiliary.
562///</summary>563///<param name="value">The value.</param>564publicvoid RemoveAuxiliary(float value)
565        {
566int num = 0;
567for (int num2 = auxiliary_lines.Count - 1; num2 >= 0; num2--)
568            {
569if (auxiliary_lines[num2].Value == value)
570                {
571                    auxiliary_lines[num2].Dispose();
572                    auxiliary_lines.RemoveAt(num2);
573                     num++;
574                }
575            }
576if (num > 0)
577            {
578                Invalidate();
579            }
580        }
581582///<summary>583/// Removes all auxiliary.
584///</summary>585publicvoid RemoveAllAuxiliary()
586        {
587int count = auxiliary_lines.Count;
588            auxiliary_lines.Clear();
589if (count > 0)
590            {
591                Invalidate();
592            }
593        }
594595///<summary>596/// Adds the auxiliary label.
597///</summary>598///<param name="auxiliaryLable">The auxiliary lable.</param>599publicvoid AddAuxiliaryLabel(AuxiliaryLable auxiliaryLable)
600        {
601            auxiliary_Labels.Add(auxiliaryLable);
602        }
603604///<summary>605/// Removes the auxiliary lable.
606///</summary>607///<param name="auxiliaryLable">The auxiliary lable.</param>608publicvoid RemoveAuxiliaryLable(AuxiliaryLable auxiliaryLable)
609        {
610if (auxiliary_Labels.Remove(auxiliaryLable))
611            {
612                Invalidate();
613            }
614        }
615616///<summary>617/// Removes all auxiliary lable.
618///</summary>619publicvoid RemoveAllAuxiliaryLable()
620        {
621int count = auxiliary_Labels.Count;
622            auxiliary_Labels.Clear();
623if (count > 0)
624            {
625                Invalidate();
626            }
627        }
628629///<summary>630/// Adds the mark text.
631///</summary>632///<param name="markText">The mark text.</param>633publicvoid AddMarkText(MarkText markText)
634        {
635            MarkTexts.Add(markText);
636if (data_list.Count > 0)
637            {
638                Invalidate();
639            }
640        }
641642///<summary>643/// Adds the mark text.
644///</summary>645///<param name="strCurveKey">The string curve key.</param>646///<param name="intValueIndex">Index of the int value.</param>647///<param name="strText">The string text.</param>648///<param name="textColor">Color of the text.</param>649publicvoid AddMarkText(string strCurveKey, int intValueIndex, string strText, Color? textColor = null)
650        {
651             AddMarkText(new MarkText() { CurveKey = strCurveKey, PositionStyle = MarkTextPositionStyle.Auto, Text = strText, TextColor = textColor, Index = intValueIndex });
652        }
653654///<summary>655/// Removes the mark text.
656///</summary>657///<param name="markText">The mark text.</param>658publicvoid RemoveMarkText(MarkText markText)
659        {
660            MarkTexts.Remove(markText);
661if (data_list.Count > 0)
662            {
663                Invalidate();
664            }
665        }
666667///<summary>668/// Removes all mark text.
669///</summary>670publicvoid RemoveAllMarkText()
671        {
672            MarkTexts.Clear();
673if (data_list.Count > 0)
674            {
675                Invalidate();
676            }
677         }

其中

MarkText为标注文字相关

AuxiliaryLabel为提示信息相关

Auxiliary为节点信息相关

 

完整代码

技术分享图片 技术分享图片
                   1
                //
                 ***********************************************************************

                   2
                //
                 Assembly         : HZH_Controls

                   3
                //
                 Created          : 2019-09-23

                   4
                //
                   5
                //
                 ***********************************************************************

                   6
                //
                 <copyright file="UCCurve.cs">

                   7
                //
                     Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:623128629@qq.com

                   8
                //
                 </copyright>

                   9
                //
                  10
                //
                 Blog: 
                https://www.cnblogs.com/bfyx
                  11
                //
                 GitHub:
                https://github.com/kwwwvagaa/NetWinformControl
                  12
                //
                 gitee:
                https://gitee.com/kwwwvagaa/net_winform_custom_control.git
                  13
                //
                  14
                //
                 If you use this code, please keep this note.

                  15
                //
                 ***********************************************************************
                  16
                using
                 System;

                  17
                using
                 System.Collections.Generic;

                  18
                using
                 System.ComponentModel;

                  19
                using
                 System.Drawing;

                  20
                using
                 System.Drawing.Drawing2D;

                  21
                using
                 System.Drawing.Text;

                  22
                using
                 System.Windows.Forms;

                  23
                  24
                namespace
                 HZH_Controls.Controls

                  25
                {

                  26
                ///
                <summary>
                  27
                ///
                 Class UCCurve.

                  28
                ///
                 Implements the 
                <see cref="System.Windows.Forms.UserControl" />
                  29
                ///
                </summary>
                  30
                ///
                <seealso cref="System.Windows.Forms.UserControl" />
                  31
                public
                class
                 UCCurve : UserControl

                  32
                    {

                  33
                ///
                <summary>
                  34
                ///
                 The value count maximum

                  35
                ///
                </summary>
                  36
                private
                const
                int value_count_max = 4096;
  37  38///<summary>  39/// The value maximum left
  40///</summary>  41privatefloat value_max_left = 100f;
  42  43///<summary>  44/// The value minimum left
  45///</summary>  46privatefloat value_min_left = 0f;
  47  48///<summary>  49/// The value maximum right
  50///</summary>  51privatefloat value_max_right = 100f;
  52  53///<summary>  54/// The value minimum right
  55///</summary>  56privatefloat value_min_right = 0f;
  57  58///<summary>  59/// The value segment
  60///</summary>  61privateint value_Segment = 5;
  62  63///<summary>  64/// The value is abscissa strech
  65///</summary>  66privatebool value_IsAbscissaStrech = false;
  67  68///<summary>  69/// The value strech data count maximum
  70///</summary>  71privateint value_StrechDataCountMax = 300;
  72  73///<summary>  74/// The value is render dash line
  75///</summary>  76privatebool value_IsRenderDashLine = true;
  77  78///<summary>  79/// The text format
  80///</summary>  81privatestring textFormat = "HH:mm";
  82  83///<summary>  84/// The value interval abscissa text
  85///</summary>  86privateint value_IntervalAbscissaText = 100;
  87  88///<summary>  89/// The random
  90///</summary>  91private Random random = null;
  92  93///<summary>  94/// The value title
  95///</summary>  96privatestring value_title = "";
  97  98///<summary>  99/// The left right
 100///</summary> 101privateint leftRight = 50;
 102 103///<summary> 104/// Up dowm
 105///</summary> 106privateint upDowm = 50;
 107 108///<summary> 109/// The data list
 110///</summary> 111private Dictionary<string, CurveItem> data_list = null;
 112 113///<summary> 114/// The data text
 115///</summary> 116privatestring[] data_text = null;
 117 118///<summary> 119/// The auxiliary lines
 120///</summary> 121private List<AuxiliaryLine> auxiliary_lines;
 122 123///<summary> 124/// The auxiliary labels
 125///</summary> 126private List<AuxiliaryLable> auxiliary_Labels;
 127 128///<summary> 129/// The mark texts
 130///</summary> 131private List<MarkText> MarkTexts;
 132 133///<summary> 134/// The font size9
 135///</summary> 136private Font font_size9 = null;
 137 138///<summary> 139/// The font size12
 140///</summary> 141private Font font_size12 = null;
 142 143///<summary> 144/// The brush deep
 145///</summary> 146private Brush brush_deep = null;
 147 148///<summary> 149/// The pen normal
 150///</summary> 151private Pen pen_normal = null;
 152 153///<summary> 154/// The pen dash
 155///</summary> 156private Pen pen_dash = null;
 157 158///<summary> 159/// The color normal
 160///</summary> 161private Color color_normal = Color.DeepPink;
 162 163///<summary> 164/// The color deep
 165///</summary> 166private Color color_deep = Color.DimGray;
 167 168///<summary> 169/// The color dash
 170///</summary> 171private Color color_dash = Color.FromArgb(232, 232, 232);
 172 173///<summary> 174/// The color mark font
 175///</summary> 176private Color color_mark_font = Color.DodgerBlue;
 177 178///<summary> 179/// The brush mark font
 180///</summary> 181private Brush brush_mark_font = Brushes.DodgerBlue;
 182 183///<summary> 184/// The format left
 185///</summary> 186private StringFormat format_left = null;
 187 188///<summary> 189/// The format right
 190///</summary> 191private StringFormat format_right = null;
 192 193///<summary> 194/// The format center
 195///</summary> 196private StringFormat format_center = null;
 197 198///<summary> 199/// The is render right coordinate
 200///</summary> 201privatebool isRenderRightCoordinate = true;
 202 203///<summary> 204/// The curve name width
 205///</summary> 206privateint curveNameWidth = 100;
 207 208///<summary> 209/// The components
 210///</summary> 211private IContainer components = null;
 212 213///<summary> 214/// 获取或设置控件的背景色。
 215///</summary> 216///<value>The color of the back.</value> 217///<PermissionSet> 218///<IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /> 219///</PermissionSet> 220         [Browsable(true)]
 221         [Description("获取或设置控件的背景色")]
 222         [Category("自定义")]
 223         [DefaultValue(typeof(Color), "Transparent")]
 224        [EditorBrowsable(EditorBrowsableState.Always)]
 225publicoverride Color BackColor
 226        {
 227get 228            {
 229returnbase.BackColor;
 230            }
 231set 232            {
 233base.BackColor = value;
 234            }
 235        }
 236 237///<summary> 238/// Gets or sets the value maximum left.
 239///</summary> 240///<value>The value maximum left.</value> 241         [Category("自定义")]
 242         [Description("获取或设置图形的左纵坐标的最大值,该值必须大于最小值")]
 243         [Browsable(true)]
 244        [DefaultValue(100f)]
 245publicfloat ValueMaxLeft
 246        {
 247get 248            {
 249return value_max_left;
 250            }
 251set 252            {
 253                 value_max_left = value;
 254                Invalidate();
 255            }
 256        }
 257 258///<summary> 259/// Gets or sets the value minimum left.
 260///</summary> 261///<value>The value minimum left.</value> 262         [Category("自定义")]
 263         [Description("获取或设置图形的左纵坐标的最小值,该值必须小于最大值")]
 264         [Browsable(true)]
 265        [DefaultValue(0f)]
 266publicfloat ValueMinLeft
 267        {
 268get 269            {
 270return value_min_left;
 271            }
 272set 273            {
 274                 value_min_left = value;
 275                Invalidate();
 276            }
 277        }
 278 279///<summary> 280/// Gets or sets the value maximum right.
 281///</summary> 282///<value>The value maximum right.</value> 283         [Category("自定义")]
 284         [Description("获取或设置图形的右纵坐标的最大值,该值必须大于最小值")]
 285         [Browsable(true)]
 286        [DefaultValue(100f)]
 287publicfloat ValueMaxRight
 288        {
 289get 290            {
 291return value_max_right;
 292            }
 293set 294            {
 295                 value_max_right = value;
 296                Invalidate();
 297            }
 298        }
 299 300///<summary> 301/// Gets or sets the value minimum right.
 302///</summary> 303///<value>The value minimum right.</value> 304         [Category("自定义")]
 305         [Description("获取或设置图形的右纵坐标的最小值,该值必须小于最大值")]
 306         [Browsable(true)]
 307        [DefaultValue(0f)]
 308publicfloat ValueMinRight
 309        {
 310get 311            {
 312return value_min_right;
 313            }
 314set 315            {
 316                 value_min_right = value;
 317                Invalidate();
 318            }
 319        }
 320 321///<summary> 322/// Gets or sets the value segment.
 323///</summary> 324///<value>The value segment.</value> 325         [Category("自定义")]
 326         [Description("获取或设置图形的纵轴分段数")]
 327         [Browsable(true)]
 328         [DefaultValue(5)]
 329publicint ValueSegment
 330        {
 331get 332            {
 333return value_Segment;
 334            }
 335set 336            {
 337                 value_Segment = value;
 338                Invalidate();
 339            }
 340        }
 341 342///<summary> 343/// Gets or sets a value indicating whether this instance is abscissa strech.
 344///</summary> 345///<value><c>true</c> if this instance is abscissa strech; otherwise, <c>false</c>.</value> 346         [Category("自定义")]
 347         [Description("获取或设置所有的数据是否强制在一个界面里显示")]
 348         [Browsable(true)]
 349         [DefaultValue(false)]
 350publicbool IsAbscissaStrech
 351        {
 352get 353            {
 354return value_IsAbscissaStrech;
 355            }
 356set 357            {
 358                 value_IsAbscissaStrech = value;
 359                Invalidate();
 360            }
 361        }
 362 363///<summary> 364/// Gets or sets the strech data count maximum.
 365///</summary> 366///<value>The strech data count maximum.</value> 367         [Category("自定义")]
 368         [Description("获取或设置拉伸模式下的最大数据量")]
 369         [Browsable(true)]
 370         [DefaultValue(300)]
 371publicint StrechDataCountMax
 372        {
 373get 374            {
 375return value_StrechDataCountMax;
 376            }
 377set 378            {
 379                 value_StrechDataCountMax = value;
 380                Invalidate();
 381            }
 382        }
 383 384///<summary> 385/// Gets or sets a value indicating whether this instance is render dash line.
 386///</summary> 387///<value><c>true</c> if this instance is render dash line; otherwise, <c>false</c>.</value> 388         [Category("自定义")]
 389         [Description("获取或设置虚线是否进行显示")]
 390         [Browsable(true)]
 391         [DefaultValue(true)]
 392publicbool IsRenderDashLine
 393        {
 394get 395            {
 396return value_IsRenderDashLine;
 397            }
 398set 399            {
 400                 value_IsRenderDashLine = value;
 401                Invalidate();
 402            }
 403        }
 404 405///<summary> 406/// Gets or sets the color lines and text.
 407///</summary> 408///<value>The color lines and text.</value> 409         [Category("自定义")]
 410         [Description("获取或设置坐标轴及相关信息文本的颜色")]
 411         [Browsable(true)]
 412         [DefaultValue(typeof(Color), "DimGray")]
 413public Color ColorLinesAndText
 414        {
 415get 416            {
 417return color_deep;
 418            }
 419set 420            {
 421                 color_deep = value;
 422                InitializationColor();
 423                Invalidate();
 424            }
 425        }
 426 427///<summary> 428/// Gets or sets the color dash lines.
 429///</summary> 430///<value>The color dash lines.</value> 431         [Category("自定义")]
 432         [Description("获取或设置虚线的颜色")]
 433         [Browsable(true)]
 434public Color ColorDashLines
 435        {
 436get 437            {
 438return color_dash;
 439            }
 440set 441            {
 442                 color_dash = value;
 443if (pen_dash != null)
 444                    pen_dash.Dispose();
 445                 pen_dash = new Pen(color_dash);
 446                 pen_dash.DashStyle = DashStyle.Custom;
 447                 pen_dash.DashPattern = newfloat[2]
 448                {
 449                    5f,
 450                    5f
 451                };
 452                Invalidate();
 453            }
 454        }
 455 456///<summary> 457/// Gets or sets the interval abscissa text.
 458///</summary> 459///<value>The interval abscissa text.</value> 460         [Category("自定义")]
 461         [Description("获取或设置纵向虚线的分隔情况,单位为多少个数据")]
 462         [Browsable(true)]
 463         [DefaultValue(100)]
 464publicint IntervalAbscissaText
 465        {
 466get 467            {
 468return value_IntervalAbscissaText;
 469            }
 470set 471            {
 472                 value_IntervalAbscissaText = value;
 473                Invalidate();
 474            }
 475        }
 476 477///<summary> 478/// Gets or sets the text add format.
 479///</summary> 480///<value>The text add format.</value> 481         [Category("自定义")]
 482         [Description("获取或设置实时数据新增时文本相对应于时间的格式化字符串,默认HH:mm")]
 483         [Browsable(true)]
 484         [DefaultValue("HH:mm")]
 485publicstring TextAddFormat
 486        {
 487get 488            {
 489return textFormat;
 490            }
 491set 492            {
 493                 textFormat = value;
 494                Invalidate();
 495            }
 496        }
 497 498///<summary> 499/// Gets or sets the title.
 500///</summary> 501///<value>The title.</value> 502         [Category("自定义")]
 503         [Description("获取或设置图标的标题信息")]
 504         [Browsable(true)]
 505         [DefaultValue("")]
 506publicstring Title
 507        {
 508get 509            {
 510return value_title;
 511            }
 512set 513            {
 514                 value_title = value;
 515                Invalidate();
 516            }
 517        }
 518 519///<summary> 520/// Gets or sets a value indicating whether this instance is render right coordinate.
 521///</summary> 522///<value><c>true</c> if this instance is render right coordinate; otherwise, <c>false</c>.</value> 523         [Category("自定义")]
 524         [Description("获取或设置是否显示右侧的坐标系信息")]
 525         [Browsable(true)]
 526         [DefaultValue(true)]
 527publicbool IsRenderRightCoordinate
 528        {
 529get 530            {
 531return isRenderRightCoordinate;
 532            }
 533set 534            {
 535                 isRenderRightCoordinate = value;
 536                Invalidate();
 537            }
 538        }
 539 540///<summary> 541/// Gets or sets the width of the curve name.
 542///</summary> 543///<value>The width of the curve name.</value> 544         [Browsable(true)]
 545         [Description("获取或设置曲线名称的布局宽度")]
 546         [Category("自定义")]
 547         [DefaultValue(100)]
 548publicint CurveNameWidth
 549        {
 550get 551            {
 552return curveNameWidth;
 553            }
 554set 555            {
 556if (value > 10)
 557                {
 558                     curveNameWidth = value;
 559                }
 560            }
 561        }
 562 563///<summary> 564/// Initializes a new instance of the <see cref="UCCurve" /> class.
 565///</summary> 566public UCCurve()
 567        {
 568            InitializeComponent();
 569             random = new Random();
 570             data_list = new Dictionary<string, CurveItem>();
 571             auxiliary_lines = new List<AuxiliaryLine>();
 572             MarkTexts = new List<MarkText>();
 573             auxiliary_Labels = new List<AuxiliaryLable>();
 574             format_left = new StringFormat
 575            {
 576                 LineAlignment = StringAlignment.Center,
 577                 Alignment = StringAlignment.Near
 578            };
 579             format_right = new StringFormat
 580            {
 581                 LineAlignment = StringAlignment.Center,
 582                 Alignment = StringAlignment.Far
 583            };
 584             format_center = new StringFormat
 585            {
 586                 LineAlignment = StringAlignment.Center,
 587                 Alignment = StringAlignment.Center
 588            };
 589             font_size9 = new Font("微软雅黑", 9f);
 590             font_size12 = new Font("微软雅黑", 12f);
 591            InitializationColor();
 592             pen_dash = new Pen(color_deep);
 593             pen_dash.DashStyle = DashStyle.Custom;
 594             pen_dash.DashPattern = newfloat[2]
 595            {
 596                5f,
 597                5f
 598            };
 599             SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);
 600             SetStyle(ControlStyles.ResizeRedraw, true);
 601             SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
 602             SetStyle(ControlStyles.AllPaintingInWmPaint, true);
 603        }
 604 605///<summary> 606/// Initializations the color.
 607///</summary> 608privatevoid InitializationColor()
 609        {
 610if (pen_normal != null)
 611                pen_normal.Dispose();
 612if (brush_deep != null)
 613                brush_deep.Dispose();
 614             pen_normal = new Pen(color_deep);
 615             brush_deep = new SolidBrush(color_deep);
 616        }
 617 618///<summary> 619/// Sets the curve text.
 620///</summary> 621///<param name="descriptions">The descriptions.</param> 622publicvoid SetCurveText(string[] descriptions)
 623        {
 624             data_text = descriptions;
 625            Invalidate();
 626        }
 627 628///<summary> 629/// Sets the left curve.
 630///</summary> 631///<param name="key">The key.</param> 632///<param name="data">The data.</param> 633///<param name="lineColor">Color of the line.</param> 634publicvoid SetLeftCurve(string key, float[] data, Color? lineColor = null)
 635        {
 636             SetCurve(key, true, data, lineColor, 1f, false);
 637        }
 638 639///<summary> 640/// Sets the left curve.
 641///</summary> 642///<param name="key">The key.</param> 643///<param name="data">The data.</param> 644///<param name="lineColor">Color of the line.</param> 645///<param name="isSmooth">if set to <c>true</c> [is smooth].</param> 646publicvoid SetLeftCurve(string key, float[] data, Color? lineColor, bool isSmooth = false)
 647        {
 648             SetCurve(key, true, data, lineColor, 1f, isSmooth);
 649        }
 650 651///<summary> 652/// Sets the right curve.
 653///</summary> 654///<param name="key">The key.</param> 655///<param name="data">The data.</param> 656///<param name="lineColor">Color of the line.</param> 657publicvoid SetRightCurve(string key, float[] data, Color? lineColor = null)
 658        {
 659             SetCurve(key, false, data, lineColor, 1f, false);
 660        }
 661 662///<summary> 663/// Sets the right curve.
 664///</summary> 665///<param name="key">The key.</param> 666///<param name="data">The data.</param> 667///<param name="lineColor">Color of the line.</param> 668///<param name="isSmooth">if set to <c>true</c> [is smooth].</param> 669publicvoid SetRightCurve(string key, float[] data, Color? lineColor, bool isSmooth = false)
 670        {
 671             SetCurve(key, false, data, lineColor, 1f, isSmooth);
 672        }
 673 674///<summary> 675/// Sets the curve.
 676///</summary> 677///<param name="key">The key.</param> 678///<param name="isLeft">if set to <c>true</c> [is left].</param> 679///<param name="data">The data.</param> 680///<param name="lineColor">Color of the line.</param> 681///<param name="thickness">The thickness.</param> 682///<param name="isSmooth">if set to <c>true</c> [is smooth].</param> 683publicvoid SetCurve(string key, bool isLeft, float[] data, Color? lineColor, float thickness, bool isSmooth)
 684        {
 685if (data_list.ContainsKey(key))
 686            {
 687if (data == null)
 688                {
 689                     data = newfloat[0];
 690                }
 691                 data_list[key].Data = data;
 692            }
 693else 694            {
 695if (data == null)
 696                {
 697                     data = newfloat[0];
 698                }
 699                 data_list.Add(key, new CurveItem
 700                {
 701                     Data = data,
 702                     MarkText = newstring[data.Length],
 703                     LineThickness = thickness,
 704                     LineColor = lineColor ?? ControlHelper.Colors[data_list.Count + 13],
 705                     IsLeftFrame = isLeft,
 706                     IsSmoothCurve = isSmooth
 707                });
 708if (data_text == null)
 709                {
 710                     data_text = newstring[data.Length];
 711                }
 712            }
 713            Invalidate();
 714        }
 715 716///<summary> 717/// Removes the curve.
 718///</summary> 719///<param name="key">The key.</param> 720publicvoid RemoveCurve(string key)
 721        {
 722if (data_list.ContainsKey(key))
 723            {
 724                data_list.Remove(key);
 725            }
 726if (data_list.Count == 0)
 727            {
 728                 data_text = newstring[0];
 729            }
 730            Invalidate();
 731        }
 732 733///<summary> 734/// Removes all curve.
 735///</summary> 736publicvoid RemoveAllCurve()
 737        {
 738int count = data_list.Count;
 739            data_list.Clear();
 740if (data_list.Count == 0)
 741            {
 742                 data_text = newstring[0];
 743            }
 744if (count > 0)
 745            {
 746                Invalidate();
 747            }
 748        }
 749 750///<summary> 751/// Removes all curve data.
 752///</summary> 753publicvoid RemoveAllCurveData()
 754        {
 755int count = data_list.Count;
 756foreach (KeyValuePair<string, CurveItem> item in data_list)
 757            {
 758                 item.Value.Data = newfloat[0];
 759                 item.Value.MarkText = newstring[0];
 760            }
 761             data_text = newstring[0];
 762if (count > 0)
 763            {
 764                Invalidate();
 765            }
 766        }
 767 768///<summary> 769/// Gets the curve item.
 770///</summary> 771///<param name="key">The key.</param> 772///<returns>CurveItem.</returns> 773public CurveItem GetCurveItem(string key)
 774        {
 775if (data_list.ContainsKey(key))
 776            {
 777return data_list[key];
 778            }
 779returnnull;
 780        }
 781 782///<summary> 783/// Saves to bitmap.
 784///</summary> 785///<returns>Bitmap.</returns> 786public Bitmap SaveToBitmap()
 787        {
 788return SaveToBitmap(base.Width, base.Height);
 789        }
 790 791///<summary> 792/// Saves to bitmap.
 793///</summary> 794///<param name="width">The width.</param> 795///<param name="height">The height.</param> 796///<returns>Bitmap.</returns> 797public Bitmap SaveToBitmap(int width, int height)
 798        {
 799             Bitmap bitmap = new Bitmap(width, height);
 800             Graphics graphics = Graphics.FromImage(bitmap);
 801             OnPaint(new PaintEventArgs(graphics, new Rectangle(0, 0, width, height)));
 802return bitmap;
 803        }
 804 805///<summary> 806/// Adds the curve data.
 807///</summary> 808///<param name="key">The key.</param> 809///<param name="values">The values.</param> 810///<param name="markTexts">The mark texts.</param> 811///<param name="isUpdateUI">if set to <c>true</c> [is update UI].</param> 812privatevoid AddCurveData(string key, float[] values, string[] markTexts, bool isUpdateUI)
 813        {
 814if ((values != null && values.Length < 1) || !data_list.ContainsKey(key))
 815            {
 816return;
 817            }
 818             CurveItem CurveItem = data_list[key];
 819if (CurveItem.Data != null)
 820            {
 821if (value_IsAbscissaStrech)
 822                {
 823                     ControlHelper.AddArrayData(ref CurveItem.Data, values, value_StrechDataCountMax);
 824                     ControlHelper.AddArrayData(ref CurveItem.MarkText, markTexts, value_StrechDataCountMax);
 825                }
 826else 827                {
 828                     ControlHelper.AddArrayData(ref CurveItem.Data, values, 4096);
 829                     ControlHelper.AddArrayData(ref CurveItem.MarkText, markTexts, 4096);
 830                }
 831if (isUpdateUI)
 832                {
 833                    Invalidate();
 834                }
 835            }
 836        }
 837 838///<summary> 839/// Adds the curve time.
 840///</summary> 841///<param name="count">The count.</param> 842privatevoid AddCurveTime(int count)
 843        {
 844            AddCurveTime(count, DateTime.Now.ToString(textFormat));
 845        }
 846 847///<summary> 848/// Adds the curve time.
 849///</summary> 850///<param name="count">The count.</param> 851///<param name="text">The text.</param> 852privatevoid AddCurveTime(int count, string text)
 853        {
 854if (data_text != null)
 855            {
 856string[] array = newstring[count];
 857for (int i = 0; i < array.Length; i++)
 858                {
 859                     array[i] = text;
 860                }
 861if (value_IsAbscissaStrech)
 862                {
 863                     ControlHelper.AddArrayData(ref data_text, array, value_StrechDataCountMax);
 864                }
 865else 866                {
 867                     ControlHelper.AddArrayData(ref data_text, array, 4096);
 868                }
 869            }
 870        }
 871 872///<summary> 873/// Adds the curve data.
 874///</summary> 875///<param name="key">The key.</param> 876///<param name="value">The value.</param> 877publicvoid AddCurveData(string key, float value)
 878        {
 879             AddCurveData(key, newfloat[1]
 880            {
 881                value
 882            });
 883        }
 884 885///<summary> 886/// Adds the curve data.
 887///</summary> 888///<param name="key">The key.</param> 889///<param name="value">The value.</param> 890///<param name="markText">The mark text.</param> 891publicvoid AddCurveData(string key, float value, string markText)
 892        {
 893             AddCurveData(key, newfloat[1]
 894            {
 895                value
 896             }, newstring[1]
 897            {
 898                markText
 899            });
 900        }
 901 902///<summary> 903/// Adds the curve data.
 904///</summary> 905///<param name="key">The key.</param> 906///<param name="values">The values.</param> 907publicvoid AddCurveData(string key, float[] values)
 908        {
 909             AddCurveData(key, values, null);
 910        }
 911 912///<summary> 913/// Adds the curve data.
 914///</summary> 915///<param name="key">The key.</param> 916///<param name="values">The values.</param> 917///<param name="markTexts">The mark texts.</param> 918publicvoid AddCurveData(string key, float[] values, string[] markTexts)
 919        {
 920if (markTexts == null)
 921            {
 922                 markTexts = newstring[values.Length];
 923            }
 924             AddCurveData(key, values, markTexts, false);
 925if (values != null && values.Length != 0)
 926            {
 927                AddCurveTime(values.Length);
 928            }
 929            Invalidate();
 930        }
 931 932///<summary> 933/// Adds the curve data.
 934///</summary> 935///<param name="keys">The keys.</param> 936///<param name="values">The values.</param> 937publicvoid AddCurveData(string[] keys, float[] values)
 938        {
 939             AddCurveData(keys, values, null);
 940        }
 941 942///<summary> 943/// Adds the curve data.
 944///</summary> 945///<param name="axisText">The axis text.</param> 946///<param name="keys">The keys.</param> 947///<param name="values">The values.</param> 948publicvoid AddCurveData(string axisText, string[] keys, float[] values)
 949        {
 950             AddCurveData(axisText, keys, values, null);
 951        }
 952 953///<summary> 954/// Adds the curve data.
 955///</summary> 956///<param name="keys">The keys.</param> 957///<param name="values">The values.</param> 958///<param name="markTexts">The mark texts.</param> 959///<exception cref="ArgumentNullException">keys
 960/// or
 961/// values</exception> 962///<exception cref="Exception">两个参数的数组长度不一致。
 963/// or
 964/// 两个参数的数组长度不一致。</exception> 965publicvoid AddCurveData(string[] keys, float[] values, string[] markTexts)
 966        {
 967if (keys == null)
 968            {
 969thrownew ArgumentNullException("keys");
 970            }
 971if (values == null)
 972            {
 973thrownew ArgumentNullException("values");
 974            }
 975if (markTexts == null)
 976            {
 977                 markTexts = newstring[keys.Length];
 978            }
 979if (keys.Length != values.Length)
 980            {
 981thrownew Exception("两个参数的数组长度不一致。");
 982            }
 983if (keys.Length != markTexts.Length)
 984            {
 985thrownew Exception("两个参数的数组长度不一致。");
 986            }
 987for (int i = 0; i < keys.Length; i++)
 988            {
 989                 AddCurveData(keys[i], newfloat[1]
 990                {
 991                    values[i]
 992                 }, newstring[1]
 993                {
 994                    markTexts[i]
 995                 }, false);
 996            }
 997             AddCurveTime(1);
 998            Invalidate();
 999        }
10001001///<summary>1002/// Adds the curve data.
1003///</summary>1004///<param name="axisText">The axis text.</param>1005///<param name="keys">The keys.</param>1006///<param name="values">The values.</param>1007///<param name="markTexts">The mark texts.</param>1008///<exception cref="ArgumentNullException">keys
1009/// or
1010/// values</exception>1011///<exception cref="Exception">两个参数的数组长度不一致。
1012/// or
1013/// 两个参数的数组长度不一致。</exception>1014publicvoid AddCurveData(string axisText, string[] keys, float[] values, string[] markTexts)
1015        {
1016if (keys == null)
1017            {
1018thrownew ArgumentNullException("keys");
1019            }
1020if (values == null)
1021            {
1022thrownew ArgumentNullException("values");
1023            }
1024if (markTexts == null)
1025            {
1026                 markTexts = newstring[keys.Length];
1027            }
1028if (keys.Length != values.Length)
1029            {
1030thrownew Exception("两个参数的数组长度不一致。");
1031            }
1032if (keys.Length != markTexts.Length)
1033            {
1034thrownew Exception("两个参数的数组长度不一致。");
1035            }
1036for (int i = 0; i < keys.Length; i++)
1037            {
1038                 AddCurveData(keys[i], newfloat[1]
1039                {
1040                    values[i]
1041                 }, newstring[1]
1042                {
1043                    markTexts[i]
1044                 }, false);
1045            }
1046             AddCurveTime(1, axisText);
1047            Invalidate();
1048        }
10491050///<summary>1051/// Sets the curve visible.
1052///</summary>1053///<param name="key">The key.</param>1054///<param name="visible">if set to <c>true</c> [visible].</param>1055publicvoid SetCurveVisible(string key, bool visible)
1056        {
1057if (data_list.ContainsKey(key))
1058            {
1059                 CurveItem CurveItem = data_list[key];
1060                 CurveItem.Visible = visible;
1061                Invalidate();
1062            }
1063        }
10641065///<summary>1066/// Sets the curve visible.
1067///</summary>1068///<param name="keys">The keys.</param>1069///<param name="visible">if set to <c>true</c> [visible].</param>1070publicvoid SetCurveVisible(string[] keys, bool visible)
1071        {
1072foreach (string key in keys)
1073            {
1074if (data_list.ContainsKey(key))
1075                {
1076                     CurveItem CurveItem = data_list[key];
1077                     CurveItem.Visible = visible;
1078                }
1079            }
1080            Invalidate();
1081        }
10821083///<summary>1084/// Adds the left auxiliary.
1085///</summary>1086///<param name="value">The value.</param>1087publicvoid AddLeftAuxiliary(float value)
1088        {
1089            AddLeftAuxiliary(value, ColorLinesAndText);
1090        }
10911092///<summary>1093/// Adds the left auxiliary.
1094///</summary>1095///<param name="value">The value.</param>1096///<param name="lineColor">Color of the line.</param>1097publicvoid AddLeftAuxiliary(float value, Color lineColor)
1098        {
1099             AddLeftAuxiliary(value, lineColor, 1f, true);
1100        }
11011102///<summary>1103/// Adds the left auxiliary.
1104///</summary>1105///<param name="value">The value.</param>1106///<param name="lineColor">Color of the line.</param>1107///<param name="lineThickness">The line thickness.</param>1108///<param name="isDashLine">if set to <c>true</c> [is dash line].</param>1109publicvoid AddLeftAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine)
1110        {
1111             AddAuxiliary(value, lineColor, lineThickness, isDashLine, true);
1112        }
11131114///<summary>1115/// Adds the right auxiliary.
1116///</summary>1117///<param name="value">The value.</param>1118publicvoid AddRightAuxiliary(float value)
1119        {
1120            AddRightAuxiliary(value, ColorLinesAndText);
1121        }
11221123///<summary>1124/// Adds the right auxiliary.
1125///</summary>1126///<param name="value">The value.</param>1127///<param name="lineColor">Color of the line.</param>1128publicvoid AddRightAuxiliary(float value, Color lineColor)
1129        {
1130             AddRightAuxiliary(value, lineColor, 1f, true);
1131        }
11321133///<summary>1134/// Adds the right auxiliary.
1135///</summary>1136///<param name="value">The value.</param>1137///<param name="lineColor">Color of the line.</param>1138///<param name="lineThickness">The line thickness.</param>1139///<param name="isDashLine">if set to <c>true</c> [is dash line].</param>1140publicvoid AddRightAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine)
1141        {
1142             AddAuxiliary(value, lineColor, lineThickness, isDashLine, false);
1143        }
11441145///<summary>1146/// Adds the auxiliary.
1147///</summary>1148///<param name="value">The value.</param>1149///<param name="lineColor">Color of the line.</param>1150///<param name="lineThickness">The line thickness.</param>1151///<param name="isDashLine">if set to <c>true</c> [is dash line].</param>1152///<param name="isLeft">if set to <c>true</c> [is left].</param>1153privatevoid AddAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine, bool isLeft)
1154        {
1155             auxiliary_lines.Add(new AuxiliaryLine
1156            {
1157                 Value = value,
1158                 LineColor = lineColor,
1159                 PenDash = new Pen(lineColor)
1160                {
1161                     DashStyle = DashStyle.Custom,
1162                     DashPattern = newfloat[2]
1163                    {
1164                        5f,
1165                        5f
1166                    }
1167                },
1168                 PenSolid = new Pen(lineColor),
1169                 IsDashStyle = isDashLine,
1170                 IsLeftFrame = isLeft,
1171                 LineThickness = lineThickness,
1172                 LineTextBrush = new SolidBrush(lineColor)
1173            });
1174            Invalidate();
1175        }
11761177///<summary>1178/// Removes the auxiliary.
1179///</summary>1180///<param name="value">The value.</param>1181publicvoid RemoveAuxiliary(float value)
1182        {
1183int num = 0;
1184for (int num2 = auxiliary_lines.Count - 1; num2 >= 0; num2--)
1185            {
1186if (auxiliary_lines[num2].Value == value)
1187                {
1188                    auxiliary_lines[num2].Dispose();
1189                    auxiliary_lines.RemoveAt(num2);
1190                     num++;
1191                }
1192            }
1193if (num > 0)
1194            {
1195                Invalidate();
1196            }
1197        }
11981199///<summary>1200/// Removes all auxiliary.
1201///</summary>1202publicvoid RemoveAllAuxiliary()
1203        {
1204int count = auxiliary_lines.Count;
1205            auxiliary_lines.Clear();
1206if (count > 0)
1207            {
1208                Invalidate();
1209            }
1210        }
12111212///<summary>1213/// Adds the auxiliary label.
1214///</summary>1215///<param name="auxiliaryLable">The auxiliary lable.</param>1216publicvoid AddAuxiliaryLabel(AuxiliaryLable auxiliaryLable)
1217        {
1218            auxiliary_Labels.Add(auxiliaryLable);
1219        }
12201221///<summary>1222/// Removes the auxiliary lable.
1223///</summary>1224///<param name="auxiliaryLable">The auxiliary lable.</param>1225publicvoid RemoveAuxiliaryLable(AuxiliaryLable auxiliaryLable)
1226        {
1227if (auxiliary_Labels.Remove(auxiliaryLable))
1228            {
1229                Invalidate();
1230            }
1231        }
12321233///<summary>1234/// Removes all auxiliary lable.
1235///</summary>1236publicvoid RemoveAllAuxiliaryLable()
1237        {
1238int count = auxiliary_Labels.Count;
1239            auxiliary_Labels.Clear();
1240if (count > 0)
1241            {
1242                Invalidate();
1243            }
1244        }
12451246///<summary>1247/// Adds the mark text.
1248///</summary>1249///<param name="markText">The mark text.</param>1250publicvoid AddMarkText(MarkText markText)
1251        {
1252            MarkTexts.Add(markText);
1253if (data_list.Count > 0)
1254            {
1255                Invalidate();
1256            }
1257        }
12581259///<summary>1260/// Adds the mark text.
1261///</summary>1262///<param name="strCurveKey">The string curve key.</param>1263///<param name="intValueIndex">Index of the int value.</param>1264///<param name="strText">The string text.</param>1265///<param name="textColor">Color of the text.</param>1266publicvoid AddMarkText(string strCurveKey, int intValueIndex, string strText, Color? textColor = null)
1267        {
1268             AddMarkText(new MarkText() { CurveKey = strCurveKey, PositionStyle = MarkTextPositionStyle.Auto, Text = strText, TextColor = textColor, Index = intValueIndex });
1269        }
12701271///<summary>1272/// Removes the mark text.
1273///</summary>1274///<param name="markText">The mark text.</param>1275publicvoid RemoveMarkText(MarkText markText)
1276        {
1277            MarkTexts.Remove(markText);
1278if (data_list.Count > 0)
1279            {
1280                Invalidate();
1281            }
1282        }
12831284///<summary>1285/// Removes all mark text.
1286///</summary>1287publicvoid RemoveAllMarkText()
1288        {
1289            MarkTexts.Clear();
1290if (data_list.Count > 0)
1291            {
1292                Invalidate();
1293            }
1294        }
12951296///<summary>1297/// 引发 <see cref="E:System.Windows.Forms.Control.MouseMove" /> 事件。
1298///</summary>1299///<param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.MouseEventArgs" /></param>1300protectedoverridevoid OnMouseMove(MouseEventArgs e)
1301        {
1302base.OnMouseMove(e);
1303bool flag = false;
1304foreach (KeyValuePair<string, CurveItem> item in data_list)
1305            {
1306if (item.Value.TitleRegion.Contains(e.Location))
1307                {
1308                     flag = true;
1309break;
1310                }
1311            }
1312             Cursor = (flag ? Cursors.Hand : Cursors.Arrow);
1313        }
13141315///<summary>1316/// Handles the <see cref="E:MouseDown" /> event.
1317///</summary>1318///<param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.MouseEventArgs" /></param>1319protectedoverridevoid OnMouseDown(MouseEventArgs e)
1320        {
1321base.OnMouseDown(e);
1322foreach (KeyValuePair<string, CurveItem> item in data_list)
1323            {
1324if (item.Value.TitleRegion.Contains(e.Location))
1325                {
1326                     item.Value.LineRenderVisiable = !item.Value.LineRenderVisiable;
1327                    Invalidate();
1328break;
1329                }
1330            }
1331        }
13321333///<summary>1334/// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
1335///</summary>1336///<param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" /></param>1337protectedoverridevoid OnPaint(PaintEventArgs e)
1338        {
1339try1340            {
1341                 Graphics graphics = e.Graphics;
1342                graphics.SetGDIHigh();
1343if (BackColor != Color.Transparent)
1344                {
1345                    graphics.Clear(BackColor);
1346                }
1347int width = base.Width;
1348int height = base.Height;
1349if (width < 120 || height < 60)
1350                {
1351return;
1352                }
1353                 Point[] array = new Point[4]
1354                {
1355new Point(leftRight - 1, upDowm - 8),
1356new Point(leftRight - 1, height - upDowm),
1357new Point(width - leftRight, height - upDowm),
1358new Point(width - leftRight, upDowm - 8)
1359                };
1360                 graphics.DrawLine(pen_normal, array[0], array[1]);
1361                 graphics.DrawLine(pen_normal, array[1], array[2]);
1362if (isRenderRightCoordinate)
1363                {
1364                     graphics.DrawLine(pen_normal, array[2], array[3]);
1365                }
13661367if (!string.IsNullOrEmpty(value_title))
1368                {
1369                     graphics.DrawString(value_title, font_size9, brush_deep, new Rectangle(0, 0, width - 1, 20), format_center);
1370                }
13711372if (data_list.Count > 0)
1373                {
1374float num = leftRight + 10;
1375foreach (KeyValuePair<string, CurveItem> item in data_list)
1376                    {
1377if (item.Value.Visible)
1378                        {
1379var titleSize=graphics.MeasureString(item.Key, Font);
1380                             SolidBrush solidBrush = item.Value.LineRenderVisiable ? new SolidBrush(item.Value.LineColor) : new SolidBrush(Color.FromArgb(80, item.Value.LineColor));
1381                             graphics.FillRectangle(solidBrush, num + 8f, 24f, 20f, 14f);
1382                             graphics.DrawString(item.Key, Font, solidBrush, new PointF(num + 30f, 24f+(14 - titleSize.Height) / 2));
1383                             item.Value.TitleRegion = new RectangleF(num, 24f, 60f, 18f);
1384                            solidBrush.Dispose();
1385                             num += titleSize.Width + 30;
1386                        }
1387                    }
1388                }
138913901391for (int i = 0; i < auxiliary_Labels.Count; i++)
1392                {
1393if (!string.IsNullOrEmpty(auxiliary_Labels[i].Text))
1394                    {
1395int num2 = (auxiliary_Labels[i].LocationX > 1f) ? ((int)auxiliary_Labels[i].LocationX) : ((int)(auxiliary_Labels[i].LocationX * (float)width));
1396int num3 = (int)graphics.MeasureString(auxiliary_Labels[i].Text, Font).Width + 3;
1397                         Point[] points = new Point[6]
1398                    {
1399new Point(num2, 11),
1400new Point(num2 + 10, 20),
1401new Point(num2 + num3 + 10, 20),
1402new Point(num2 + num3 + 10, 0),
1403new Point(num2 + 10, 0),
1404new Point(num2, 11)
1405                    };
1406                        graphics.FillPolygon(auxiliary_Labels[i].TextBack, points);
1407                         graphics.DrawString(auxiliary_Labels[i].Text, Font, auxiliary_Labels[i].TextBrush, new Rectangle(num2 + 7, 0, num3 + 3, 20), format_center);
1408                    }
1409                }
1410                 ControlHelper.PaintTriangle(graphics, brush_deep, new Point(leftRight - 1, upDowm - 8), 4, GraphDirection.Upward);
1411if (isRenderRightCoordinate)
1412                {
1413                     ControlHelper.PaintTriangle(graphics, brush_deep, new Point(width - leftRight, upDowm - 8), 4, GraphDirection.Upward);
1414                }
1415for (int j = 0; j < auxiliary_lines.Count; j++)
1416                {
1417if (auxiliary_lines[j].IsLeftFrame)
1418                    {
1419                         auxiliary_lines[j].PaintValue = ControlHelper.ComputePaintLocationY(value_max_left, value_min_left, height - upDowm - upDowm, auxiliary_lines[j].Value) + (float)upDowm;
1420                    }
1421else1422                    {
1423                         auxiliary_lines[j].PaintValue = ControlHelper.ComputePaintLocationY(value_max_right, value_min_right, height - upDowm - upDowm, auxiliary_lines[j].Value) + (float)upDowm;
1424                    }
1425                }
1426for (int k = 0; k <= value_Segment; k++)
1427                {
1428float value = (float)((double)k * (double)(value_max_left - value_min_left) / (double)value_Segment + (double)value_min_left);
1429float num4 = ControlHelper.ComputePaintLocationY(value_max_left, value_min_left, height - upDowm - upDowm, value) + (float)upDowm;
1430if (IsNeedPaintDash(num4))
1431                    {
1432                         graphics.DrawLine(pen_normal, leftRight - 4, num4, leftRight - 1, num4);
1433                         RectangleF layoutRectangle = new RectangleF(0f, num4 - 9f, leftRight - 4, 20f);
1434                        graphics.DrawString(value.ToString(), font_size9, brush_deep, layoutRectangle, format_right);
1435if (isRenderRightCoordinate)
1436                        {
1437float num5 = (float)k * (value_max_right - value_min_right) / (float)value_Segment + value_min_right;
1438                             graphics.DrawLine(pen_normal, width - leftRight + 1, num4, width - leftRight + 4, num4);
1439                             layoutRectangle.Location = new PointF(width - leftRight + 4, num4 - 9f);
1440                            graphics.DrawString(num5.ToString(), font_size9, brush_deep, layoutRectangle, format_left);
1441                        }
1442if (k > 0 && value_IsRenderDashLine)
1443                        {
1444                             graphics.DrawLine(pen_dash, leftRight, num4, width - leftRight, num4);
1445                        }
1446                    }
1447                }
1448if (value_IsRenderDashLine)
1449                {
1450if (value_IsAbscissaStrech)
1451                    {
1452float num6 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
1453int num7 = CalculateDataCountByOffect(num6);
1454for (int l = 0; l < value_StrechDataCountMax; l += num7)
1455                        {
1456if (l > 0 && l < value_StrechDataCountMax - 1)
1457                            {
1458                                 graphics.DrawLine(pen_dash, (float)l * num6 + (float)leftRight, upDowm, (float)l * num6 + (float)leftRight, height - upDowm - 1);
1459                            }
1460if (data_text != null && l < data_text.Length && (float)l * num6 + (float)leftRight < (float)(data_text.Length - 1) * num6 + (float)leftRight - 40f)
1461                            {
1462                                 graphics.DrawString(layoutRectangle: new Rectangle((int)((float)l * num6), height - upDowm + 1, leftRight * 2, upDowm), s: data_text[l], font: font_size9, brush: brush_deep, format: format_center);
1463                            }
1464                        }
1465string[] array2 = data_text;
1466if (array2 != null && array2.Length > 1)
1467                        {
1468if (data_text.Length < value_StrechDataCountMax)
1469                            {
1470                                 graphics.DrawLine(pen_dash, (float)(data_text.Length - 1) * num6 + (float)leftRight, upDowm, (float)(data_text.Length - 1) * num6 + (float)leftRight, height - upDowm - 1);
1471                            }
1472                             graphics.DrawString(layoutRectangle: new Rectangle((int)((float)(data_text.Length - 1) * num6 + (float)leftRight) - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[data_text.Length - 1], font: font_size9, brush: brush_deep, format: format_center);
1473                        }
1474                    }
1475elseif (value_IntervalAbscissaText > 0)
1476                    {
1477int num8 = width - 2 * leftRight + 1;
1478for (int m = leftRight; m < width - leftRight; m += value_IntervalAbscissaText)
1479                        {
1480if (m != leftRight)
1481                            {
1482                                 graphics.DrawLine(pen_dash, m, upDowm, m, height - upDowm - 1);
1483                            }
1484if (data_text == null)
1485                            {
1486continue;
1487                            }
1488int num9 = (num8 > data_text.Length) ? data_text.Length : num8;
1489if (m - leftRight < data_text.Length && num9 - (m - leftRight) > 40)
1490                            {
1491if (data_text.Length <= num8)
1492                                {
1493                                     graphics.DrawString(layoutRectangle: new Rectangle(m - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[m - leftRight], font: font_size9, brush: brush_deep, format: format_center);
1494                                }
1495else1496                                {
1497                                     graphics.DrawString(layoutRectangle: new Rectangle(m - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[m - leftRight + data_text.Length - num8], font: font_size9, brush: brush_deep, format: format_center);
1498                                }
1499                            }
1500                        }
1501string[] array3 = data_text;
1502if (array3 != null && array3.Length > 1)
1503                        {
1504if (data_text.Length >= num8)
1505                            {
1506                                 graphics.DrawString(layoutRectangle: new Rectangle(width - leftRight - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[data_text.Length - 1], font: font_size9, brush: brush_deep, format: format_center);
1507                            }
1508else1509                            {
1510                                 graphics.DrawLine(pen_dash, data_text.Length + leftRight - 1, upDowm, data_text.Length + leftRight - 1, height - upDowm - 1);
1511                                 graphics.DrawString(layoutRectangle: new Rectangle(data_text.Length + leftRight - 1 - leftRight, height - upDowm + 1, leftRight * 2, upDowm), s: data_text[data_text.Length - 1], font: font_size9, brush: brush_deep, format: format_center);
1512                            }
1513                        }
1514                    }
1515                }
1516for (int n = 0; n < auxiliary_lines.Count; n++)
1517                {
1518if (auxiliary_lines[n].IsLeftFrame)
1519                    {
1520                         graphics.DrawLine(auxiliary_lines[n].GetPen(), leftRight - 4, auxiliary_lines[n].PaintValue, leftRight - 1, auxiliary_lines[n].PaintValue);
1521                         graphics.DrawString(layoutRectangle: new RectangleF(0f, auxiliary_lines[n].PaintValue - 9f, leftRight - 4, 20f), s: auxiliary_lines[n].Value.ToString(), font: font_size9, brush: auxiliary_lines[n].LineTextBrush, format: format_right);
1522                    }
1523else1524                    {
1525                         graphics.DrawLine(auxiliary_lines[n].GetPen(), width - leftRight + 1, auxiliary_lines[n].PaintValue, width - leftRight + 4, auxiliary_lines[n].PaintValue);
1526                         graphics.DrawString(layoutRectangle: new RectangleF(width - leftRight + 4, auxiliary_lines[n].PaintValue - 9f, leftRight - 4, 20f), s: auxiliary_lines[n].Value.ToString(), font: font_size9, brush: auxiliary_lines[n].LineTextBrush, format: format_left);
1527                    }
1528                     graphics.DrawLine(auxiliary_lines[n].GetPen(), leftRight, auxiliary_lines[n].PaintValue, width - leftRight, auxiliary_lines[n].PaintValue);
1529                }
1530if (value_IsAbscissaStrech)
1531                {
1532foreach (MarkText MarkText in MarkTexts)
1533                    {
1534foreach (KeyValuePair<string, CurveItem> item2 in data_list)
1535                        {
1536if (item2.Value.Visible && item2.Value.LineRenderVisiable && !(item2.Key != MarkText.CurveKey))
1537                            {
1538float[] data = item2.Value.Data;
1539if (data != null && data.Length > 1)
1540                                {
1541float num10 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
1542if (MarkText.Index >= 0 && MarkText.Index < item2.Value.Data.Length)
1543                                    {
1544                                         PointF pointF = new PointF((float)leftRight + (float)MarkText.Index * num10, ControlHelper.ComputePaintLocationY(item2.Value.IsLeftFrame ? value_max_left : value_max_right, item2.Value.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, item2.Value.Data[MarkText.Index]) + (float)upDowm);
1545                                         graphics.FillEllipse(new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X - 3f, pointF.Y - 3f, 6f, 6f));
1546switch ((MarkText.PositionStyle == MarkTextPositionStyle.Auto) ? MarkText.CalculateDirectionFromDataIndex(item2.Value.Data, MarkText.Index) : MarkText.PositionStyle)
1547                                        {
1548case MarkTextPositionStyle.Left:
1549                                                 graphics.DrawString(MarkText.Text, Font, new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X - 100f, pointF.Y - (float)Font.Height, 100 - MarkText.MarkTextOffect, Font.Height * 2), format_right);
1550break;
1551case MarkTextPositionStyle.Up:
1552                                                 graphics.DrawString(MarkText.Text, Font, new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X - 100f, pointF.Y - (float)Font.Height - (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
1553break;
1554case MarkTextPositionStyle.Right:
1555                                                 graphics.DrawString(MarkText.Text, Font, new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X + (float)MarkText.MarkTextOffect, pointF.Y - (float)Font.Height, 100f, Font.Height * 2), format_left);
1556break;
1557case MarkTextPositionStyle.Down:
1558                                                 graphics.DrawString(MarkText.Text, Font, new SolidBrush(MarkText.TextColor ?? item2.Value.LineColor), new RectangleF(pointF.X - 100f, pointF.Y + (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
1559break;
1560                                        }
1561                                    }
1562                                }
1563                            }
1564                        }
1565                    }
1566foreach (CurveItem value2 in data_list.Values)
1567                    {
1568if (value2.Visible && value2.LineRenderVisiable)
1569                        {
1570float[] data2 = value2.Data;
1571if (data2 != null && data2.Length > 1)
1572                            {
1573float num11 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
1574                                 PointF[] array4 = new PointF[value2.Data.Length];
1575for (int num12 = 0; num12 < value2.Data.Length; num12++)
1576                                {
1577                                     array4[num12].X = (float)leftRight + (float)num12 * num11;
1578                                     array4[num12].Y = ControlHelper.ComputePaintLocationY(value2.IsLeftFrame ? value_max_left : value_max_right, value2.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, value2.Data[num12]) + (float)upDowm;
1579if (!string.IsNullOrEmpty(value2.MarkText[num12]))
1580                                    {
1581using (Brush brush = new SolidBrush(value2.LineColor))
1582                                        {
1583                                             graphics.FillEllipse(brush, new RectangleF(array4[num12].X - 3f, array4[num12].Y - 3f, 6f, 6f));
1584switch (MarkText.CalculateDirectionFromDataIndex(value2.Data, num12))
1585                                            {
1586case MarkTextPositionStyle.Left:
1587                                                     graphics.DrawString(value2.MarkText[num12], Font, brush, new RectangleF(array4[num12].X - 100f, array4[num12].Y - (float)Font.Height, 100 - MarkText.MarkTextOffect, Font.Height * 2), format_right);
1588break;
1589case MarkTextPositionStyle.Up:
1590                                                     graphics.DrawString(value2.MarkText[num12], Font, brush, new RectangleF(array4[num12].X - 100f, array4[num12].Y - (float)Font.Height - (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
1591break;
1592case MarkTextPositionStyle.Right:
1593                                                     graphics.DrawString(value2.MarkText[num12], Font, brush, new RectangleF(array4[num12].X + (float)MarkText.MarkTextOffect, array4[num12].Y - (float)Font.Height, 100f, Font.Height * 2), format_left);
1594break;
1595case MarkTextPositionStyle.Down:
1596                                                     graphics.DrawString(value2.MarkText[num12], Font, brush, new RectangleF(array4[num12].X - 100f, array4[num12].Y + (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
1597break;
1598                                            }
1599                                        }
1600                                    }
1601                                }
1602using (Pen pen2 = new Pen(value2.LineColor, value2.LineThickness))
1603                                {
1604if (value2.IsSmoothCurve)
1605                                    {
1606                                        graphics.DrawCurve(pen2, array4);
1607                                    }
1608else1609                                    {
1610                                        graphics.DrawLines(pen2, array4);
1611                                    }
1612                                }
1613                            }
1614                        }
1615                    }
1616                }
1617else1618                {
1619foreach (MarkText MarkText2 in MarkTexts)
1620                    {
1621foreach (KeyValuePair<string, CurveItem> item3 in data_list)
1622                        {
1623if (item3.Value.Visible && item3.Value.LineRenderVisiable && !(item3.Key != MarkText2.CurveKey))
1624                            {
1625float[] data3 = item3.Value.Data;
1626if (data3 != null && data3.Length > 1 && MarkText2.Index >= 0 && MarkText2.Index < item3.Value.Data.Length)
1627                                {
1628                                     PointF pointF2 = new PointF(leftRight + MarkText2.Index, ControlHelper.ComputePaintLocationY(item3.Value.IsLeftFrame ? value_max_left : value_max_right, item3.Value.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, item3.Value.Data[MarkText2.Index]) + (float)upDowm);
1629                                     graphics.FillEllipse(new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X - 3f, pointF2.Y - 3f, 6f, 6f));
1630switch ((MarkText2.PositionStyle == MarkTextPositionStyle.Auto) ? MarkText.CalculateDirectionFromDataIndex(item3.Value.Data, MarkText2.Index) : MarkText2.PositionStyle)
1631                                    {
1632case MarkTextPositionStyle.Left:
1633                                             graphics.DrawString(MarkText2.Text, Font, new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X - 100f, pointF2.Y - (float)Font.Height, 100 - MarkText.MarkTextOffect, Font.Height * 2), format_right);
1634break;
1635case MarkTextPositionStyle.Up:
1636                                             graphics.DrawString(MarkText2.Text, Font, new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X - 100f, pointF2.Y - (float)Font.Height - (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
1637break;
1638case MarkTextPositionStyle.Right:
1639                                             graphics.DrawString(MarkText2.Text, Font, new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X + (float)MarkText.MarkTextOffect, pointF2.Y - (float)Font.Height, 100f, Font.Height * 2), format_left);
1640break;
1641case MarkTextPositionStyle.Down:
1642                                             graphics.DrawString(MarkText2.Text, Font, new SolidBrush(MarkText2.TextColor ?? item3.Value.LineColor), new RectangleF(pointF2.X - 100f, pointF2.Y + (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
1643break;
1644                                    }
1645                                }
1646                            }
1647                        }
1648                    }
1649foreach (CurveItem value3 in data_list.Values)
1650                    {
1651if (value3.Visible && value3.LineRenderVisiable)
1652                        {
1653float[] data4 = value3.Data;
1654if (data4 != null && data4.Length > 1)
1655                            {
1656int num13 = width - 2 * leftRight + 1;
1657                                PointF[] array5;
1658if (value3.Data.Length <= num13)
1659                                {
1660                                     array5 = new PointF[value3.Data.Length];
1661for (int num14 = 0; num14 < value3.Data.Length; num14++)
1662                                    {
1663                                         array5[num14].X = leftRight + num14;
1664                                         array5[num14].Y = ControlHelper.ComputePaintLocationY(value3.IsLeftFrame ? value_max_left : value_max_right, value3.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, value3.Data[num14]) + (float)upDowm;
1665                                        DrawMarkPoint(graphics, value3.MarkText[num14], array5[num14], value3.LineColor, MarkText.CalculateDirectionFromDataIndex(value3.Data, num14));
1666                                    }
1667                                }
1668else1669                                {
1670                                     array5 = new PointF[num13];
1671for (int num15 = 0; num15 < array5.Length; num15++)
1672                                    {
1673int num16 = num15 + value3.Data.Length - num13;
1674                                         array5[num15].X = leftRight + num15;
1675                                         array5[num15].Y = ControlHelper.ComputePaintLocationY(value3.IsLeftFrame ? value_max_left : value_max_right, value3.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, value3.Data[num16]) + (float)upDowm;
1676                                        DrawMarkPoint(graphics, value3.MarkText[num16], array5[num15], value3.LineColor, MarkText.CalculateDirectionFromDataIndex(value3.Data, num16));
1677                                    }
1678                                }
1679using (Pen pen3 = new Pen(value3.LineColor, value3.LineThickness))
1680                                {
1681if (value3.IsSmoothCurve)
1682                                    {
1683                                        graphics.DrawCurve(pen3, array5);
1684                                    }
1685else1686                                    {
1687                                        graphics.DrawLines(pen3, array5);
1688                                    }
1689                                }
1690                            }
1691                        }
1692                    }
1693                }
1694base.OnPaint(e);
1695            }
1696catch (Exception exc)
1697            {
1698                 e.Graphics.DrawString(exc.Message, this.Font, Brushes.Black, 10, 10);
1699            }
1700        }
17011702///<summary>1703/// Draws the mark point.
1704///</summary>1705///<param name="g">The g.</param>1706///<param name="markText">The mark text.</param>1707///<param name="center">The center.</param>1708///<param name="color">The color.</param>1709///<param name="markTextPosition">The mark text position.</param>1710privatevoid DrawMarkPoint(Graphics g, string markText, PointF center, Color color, MarkTextPositionStyle markTextPosition)
1711        {
1712if (!string.IsNullOrEmpty(markText))
1713            {
1714using (Brush brush = new SolidBrush(color))
1715                {
1716                    DrawMarkPoint(g, markText, center, brush, markTextPosition);
1717                }
1718            }
1719        }
17201721///<summary>1722/// Draws the mark point.
1723///</summary>1724///<param name="g">The g.</param>1725///<param name="markText">The mark text.</param>1726///<param name="center">The center.</param>1727///<param name="brush">The brush.</param>1728///<param name="markTextPosition">The mark text position.</param>1729privatevoid DrawMarkPoint(Graphics g, string markText, PointF center, Brush brush, MarkTextPositionStyle markTextPosition)
1730        {
1731if (!string.IsNullOrEmpty(markText))
1732            {
1733                 g.FillEllipse(brush, new RectangleF(center.X - 3f, center.Y - 3f, 6f, 6f));
1734switch (markTextPosition)
1735                {
1736case MarkTextPositionStyle.Left:
1737                         g.DrawString(markText, Font, brush, new RectangleF(center.X - 100f, center.Y - (float)Font.Height, 100 - MarkText.MarkTextOffect, Font.Height * 2), format_right);
1738break;
1739case MarkTextPositionStyle.Up:
1740                         g.DrawString(markText, Font, brush, new RectangleF(center.X - 100f, center.Y - (float)Font.Height - (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
1741break;
1742case MarkTextPositionStyle.Right:
1743                         g.DrawString(markText, Font, brush, new RectangleF(center.X + (float)MarkText.MarkTextOffect, center.Y - (float)Font.Height, 100f, Font.Height * 2), format_left);
1744break;
1745case MarkTextPositionStyle.Down:
1746                         g.DrawString(markText, Font, brush, new RectangleF(center.X - 100f, center.Y + (float)MarkText.MarkTextOffect, 200f, Font.Height + 2), format_center);
1747break;
1748                }
1749            }
1750        }
17511752///<summary>1753/// Determines whether [is need paint dash] [the specified paint value].
1754///</summary>1755///<param name="paintValue">The paint value.</param>1756///<returns><c>true</c> if [is need paint dash] [the specified paint value]; otherwise, <c>false</c>.</returns>1757privatebool IsNeedPaintDash(float paintValue)
1758        {
1759for (int i = 0; i < auxiliary_lines.Count; i++)
1760            {
1761if (Math.Abs(auxiliary_lines[i].PaintValue - paintValue) < (float)font_size9.Height)
1762                {
1763returnfalse;
1764                }
1765            }
1766returntrue;
1767        }
17681769///<summary>1770/// Calculates the data count by offect.
1771///</summary>1772///<param name="offect">The offect.</param>1773///<returns>System.Int32.</returns>1774privateint CalculateDataCountByOffect(float offect)
1775        {
1776if (value_IntervalAbscissaText > 0)
1777            {
1778return value_IntervalAbscissaText;
1779            }
1780if (offect > 40f)
1781            {
1782return1;
1783            }
1784             offect = 40f / offect;
1785return (int)Math.Ceiling(offect);
1786        }
17871788///<summary>1789/// Releases unmanaged and - optionally - managed resources.
1790///</summary>1791///<param name="disposing">为 true 则释放托管资源和非托管资源;为 false 则仅释放非托管资源。</param>1792protectedoverridevoid Dispose(bool disposing)
1793        {
1794if (disposing && components != null)
1795            {
1796                components.Dispose();
1797            }
1798base.Dispose(disposing);
1799        }
18001801///<summary>1802/// Initializes the component.
1803///</summary>1804privatevoid InitializeComponent()
1805        {
1806            SuspendLayout();
1807base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
1808             BackColor = System.Drawing.Color.Transparent;
1809base.Name = "HslCurve";
1810base.Size = new System.Drawing.Size(417, 205);
1811             ResumeLayout(false);
1812        }
1813    }
1814 }
View Code

 

最后的话

如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧

原文:https://www.cnblogs.com/bfyx/p/11576321.html


【说明】本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!