C#自制控件:以扇形图控件为例

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。可以看到自定义控件的图形发生了变化。

根据这些基本的对控件的控制方法,可以根据需要扩展到更丰富的功能。

发表评论

电子邮件地址不会被公开。 必填项已用*标注