C#自制控件:以扇形图控件为例
C#的winform自带许多控件,在实际的工程需求中,可能需要将其中几个控件组合成一个新的控件使用,或者根据自己的设计来美化控件。这时,我们可以通过继承UserControl类,实现自定义控件的绘制。
在VS2019中,新建一个项目属性为“Windows窗体控件库”的项目。
这时出现了没有窗口边框的控件编辑界面,这时可以将工具箱中的多个工具拖到编辑界面上。
另外新建一个窗体项目进行测试控件之用,要将编写的控件应用到自己窗体上,只需要在引用中添加自定义窗口的工程即可。
在控件编辑界面上,放置一个正方形的panel,用来将扇形图绘制在panel上,再加入一个label,用于显示数值。对于控件,我们可能根据控件的特点添加属性,只需要将数据字段设为public
即可,而对于控件,一种非常常用的功能,就是当数值改变时控件的变化。我们可以这样编写:
private int _rate; [Category("自定义数据段"),Description("扇形图的数据")] public int Rate { get { return _rate; } set { if(value!=_rate) { whenValueChange(); } _rate = value; } }
这样控件的属性中就会有Rate字段,而对Rate字段的编辑对应在代码中就是value
,其类型等于Rate的类型。当控件的数值改变的时候,控件会有变化,而变化的形式可以通过定义的函数来指定。例如这里当Rate改变时,我们将按Rate数值而重新对绘扇形图进行绘制。
绘制扇形图即在panel的区域内用Graphics绘制相应度数的弧。当Rate修改的时候label也会修改。
private Brush foreBrush = Brushes.Orange; private Brush backBrush = Brushes.Azure; private void drawProcess() { var sp = Convert.ToInt32(360 * _rate*1.0 / 100); var gr = panel1.CreateGraphics(); gr.FillPie(foreBrush, panel1.ClientRectangle, 0, sp); gr.FillPie(backBrush, panel1.ClientRectangle,sp,360-sp); } private void whenValueChange() { drawProcess(); label1.Text = _rate.ToString()+"%"; }
对于控件,除了自定义属性,还能够自定义事件。自定义事件是通过定义委托函数,将委托函数定义为public
类型,即可在自定义事件中调用它。例如再对自定义属性Rate的修改的时候调用函数。定义如下的委托函数
public delegate void Rate_ValueChangedDelegate(object sender, EventArgs e); [Category("自定义事件"), Description("当Rate变更时")] public event Rate_ValueChangedDelegate Rate_ValueChanged; private void whenValueChange() { drawProcess(); label1.Text = _rate.ToString()+"%"; Rate_ValueChanged?.Invoke(this, null); }
这样就基本地实现了对控件的自定义属性与自定义事件。另外,对于使用Graphics绘制的内容,需要重写OnPaint
函数,否则当窗体需要重绘的时候(例如最小化之后再还原时)Graphics的内容会被清空。由于编写了drawProcess()
函数,只需要在OnPaint
函数调用drawProcess()
函数即可:
protected override void OnPaint(PaintEventArgs e) { drawProcess(); }
在主窗体中测试自定义控件的功能,添加引用之后可以看到工具箱中会出现新定义的控件,将之放在窗体中,控件的属性与事件中可以分别看到自定义的public字段以及相应委托函数。
再利用一个TrackBar用来调整自定义控件的Rate数值,并为trackBar1编写当trackBar1的数值修改时,让Rate跟随trackBar1的value。可以看到自定义控件的图形发生了变化。
根据这些基本的对控件的控制方法,可以根据需要扩展到更丰富的功能。