基于.NET的Windows窗体编程之WinForms自定义控件(2)

在实际应用开发中,可能UI框架的默认控件,已经不能满足实际的应用需求,或者某些功能被大量的重复应用,如果每一个使用的地方都书写大量的重复代码,则不仅会浪费精力,且让维护变得复杂,此时就需要将包含特定功能的部分封装成控件,便于重复使用。自定义控件就像造轮子,轮子造好以后,别的地方可以一键复用。今天我们以一些简单的小例子,简述基于.NET的Windows窗体编程中自定义控件的相关应用,仅供学习分享使用,如有不足之处,还请指正。

image

 

概述

 

一般而言,自定义控件,是在Visual Studio提供的默认控件不能满足实际的工作需要,才需要在现有控件的基础之上进行新的扩展,来实现自己的功能。自定义控件有自己特有的属性,事件,方法来支撑特定的功能。自定义控件封装实现的细节,可以进行方便的复用。自定义控件主要有以下三种分类,本例采用的是第三种。

  1. 用户控件(User Control),又称之为复合控件(Composite Controls),将现有的各种控件组合起来,形成一个新的控件,来满足用户的需求。复合控件的设计方式与窗体类似,具有可视化设计器。 通过视觉设计器创建、排列和修改构成控件。 控件事件和逻辑的编写方式与设计窗体时完全相同。 用户控件与其他任何控件一样放置在表单上。
  2. 扩展控件(Extended Controls):就是在现有的控件基础上,派生出一个新的控件,增加新的功能,或者修改原有功能,来满足用户需求。
  3. 自定义控件(Custom Controls):就是直接从UserControl类派生,也就是说完全由自己来设计、实现一个全新的控件,这是最灵活、最强大的方法。

今天主要讲解扩展控件,关于用户控件,可以参考前一篇文章;至于自定义控件,将在后续篇幅继续讲解。

 

扩展控件

 

如果新的控件需要继承基本控件的功能,则可以采用扩展控件,新控件包含基本控件的所有功能和视觉方面,但它为你提供了扩展它的机会。 今天我们以创建ToggleSwitch和ToggleLight为例,简述扩展控件的应用方法。

 

创建自定义控件库

 

由于自定义控件可以在创建它的项目中使用,也可也可以在引用这些用户控件库的其他项目中使用,所以为了将自定义控件单独存放,我们创建一个独立的自定义控件库“Okcoder.Winform.CustomControls”。

 

1. 准备资源

 

首先准备四张图片,分别表示ToggleSwitch的开和关两种状态图片,和ToggleLight的亮和灭两种状态图片,如下所示:

image

 

在自定义控件库项目上,点击右键,在弹出的快捷菜单选择“属性”,在打开的属性页面中,选择“资源”Tab页,然后在右侧点击“创建或打开程序集资源”,如下图所示:

image

 

点击“创建或打开程序集资源”会在项目的Properties目录中创建Resources.resx文件,如下所示:

image

 

打开Resources.resx文件,然后将图片添加为资源,这样图片就可以作为自定义控件库的资源,如下所示:

image

 

2. 创建扩展控件

 

选择控件库,然后点击右键,在弹出的快捷菜单中,选择“添加”,然后选择“新建项(W)...”,在弹出的“添加新项”对话框中,选择“自定义控件(Windows窗体)”,然后输入名称,点击“添加”按钮即可,如下图所示:

image

 

在本实例中,创建两个自定义控件,分别命名为“ToggleSwitch”和“ToggleLight”分别表示开关控件和灯泡,如下所示:

image

 

打开创建的扩展控件的代码视图,然后修改控件的继承类,默认为Control,修改为需要扩展的控件类,如Button,CheckBox等。ToggleSwitch开关控件派生自CheckBox,具备CheckBox的所有功能,如下所示:

image

 

3. 重绘控件

 

重写OnPaint方法,在OnPaint方法中,通过PaintEventArgs属性获取Graphics属性,用于绘制图像。根据IsChecked属性,分别绘制图片。当IsChecked属性为true时,绘制open图片,表示开关打开;当IsChecked属性为false时,绘制close图片,表示开关关闭;如下所示:

namespace Okcoder.Winform.CustomControls
{
    public partial class ToggleSwitch: CheckBox
    {
        public ToggleSwitch()
        {
            InitializeComponent();
            this.Appearance = Appearance.Button;
            this.FlatStyle = FlatStyle.Flat;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            var g = e.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.Clear(this.Parent.BackColor);
            if (this.Checked)
            {

                Image image = Image.FromStream(new MemoryStream(Properties.Resources.open));
                g.DrawImage(image, 0, 0, this.Width, this.Height);
            }
            else
            {
                Image image = Image.FromStream(new MemoryStream(Properties.Resources.close));
                g.DrawImage(image, 0, 0, this.Width, this.Height);
            }
        }
    }
}

 

在上述示例中,图片从程序集资源中获取,它是byte[]数组类型,需要转换为MemoryStream,然后再转换为Image图像进行绘制。ToggleLight控件的方法和ToggleSwitch一样,只是显示的图片不同,如下所示:

namespace Okcoder.Winform.CustomControls
{
    public partial class ToggleLight: CheckBox
    {
        public ToggleLight()
        {
            InitializeComponent();
            this.Appearance = Appearance.Normal;
            this.FlatStyle = FlatStyle.Flat;
            this.Enabled = true;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            var g = e.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.Clear(this.Parent.BackColor);
            if (this.Checked)
            {

                Image image = Image.FromStream(new MemoryStream(Properties.Resources.open1));
                g.DrawImage(image, 0, 0, this.Width, this.Height);
            }
            else
            {
                Image image = Image.FromStream(new MemoryStream(Properties.Resources.close1));
                g.DrawImage(image, 0, 0, this.Width, this.Height);
            }
        }
    }
}

 

应用扩展控件

 

扩展控件创建完成,且项目编译成功后,在需要应用用户控件的项目引用控件库“Okcoder.WinForm.CustomControls”,就可以在工具箱中,看到创建的自定义控件,然后拖动控件到Form表单中,如下所示:

image

 

为ToggleSwitch控件添加Click事件,如下所示:

image

 

当鼠标点击ToggleSwitch控件时,将ToggleSwitch控件的Checked属性,赋值给ToggleLight的Checked属性,属性所示:

namespace Okcoder.WinForm.Demo
{
    public partial class FrmCustomControl : Form
    {
        public FrmCustomControl()
        {
            InitializeComponent();
        }

        private void toggleSwitch1_Click(object sender, EventArgs e)
        {
            this.toggleLight1.Checked = this.toggleSwitch1.Checked;
        }
    }
}

 

运行示例

 

运行示例,当点击开关控件时,灯泡也会同时改变效果,效果如下所示:

image

以上就是《基于.NET的Windows窗体编程之WinForms自定义控件(2)》的全部内容,旨在抛砖引玉,一起学习,共同进步!!!

posted @ 2026-10-10 12:00  老码识途呀  阅读(29)  评论(0)    收藏  举报