在实际应用开发中可能UI框架的默认控件已经不能满足实际的应用需求或者某些功能被大量的重复应用如果每一个使用的地方都书写大量的重复代码则不仅会浪费精力且让维护变得复杂此时就需要将包含特定功能的部分封装成控件便于重复使用。自定义控件就像造轮子轮子造好以后别的地方可以一键复用。今天我们以一些简单的小例子简述基于.NET的Windows窗体编程中自定义控件的相关应用仅供学习分享使用如有不足之处还请指正。概述一般而言自定义控件是在Visual Studio提供的默认控件不能满足实际的工作需要才需要在现有控件的基础之上进行新的扩展来实现自己的功能。自定义控件有自己特有的属性事件方法来支撑特定的功能。自定义控件封装实现的细节可以进行方便的复用。自定义控件主要有以下三种分类本例采用的是第三种。用户控件User Control又称之为复合控件Composite Controls将现有的各种控件组合起来形成一个新的控件来满足用户的需求。复合控件的设计方式与窗体类似具有可视化设计器。 通过视觉设计器创建、排列和修改构成控件。 控件事件和逻辑的编写方式与设计窗体时完全相同。 用户控件与其他任何控件一样放置在表单上。扩展控件Extended Controls就是在现有的控件基础上派生出一个新的控件增加新的功能或者修改原有功能来满足用户需求。自定义控件Custom Controls就是直接从UserControl类派生也就是说完全由自己来设计、实现一个全新的控件这是最灵活、最强大的方法。今天主要讲解扩展控件关于用户控件可以参考前一篇文章至于自定义控件将在后续篇幅继续讲解。扩展控件如果新的控件需要继承基本控件的功能则可以采用扩展控件新控件包含基本控件的所有功能和视觉方面但它为你提供了扩展它的机会。 今天我们以创建ToggleSwitch和ToggleLight为例简述扩展控件的应用方法。创建自定义控件库由于自定义控件可以在创建它的项目中使用也可也可以在引用这些用户控件库的其他项目中使用所以为了将自定义控件单独存放我们创建一个独立的自定义控件库“Okcoder.Winform.CustomControls”。1. 准备资源首先准备四张图片分别表示ToggleSwitch的开和关两种状态图片和ToggleLight的亮和灭两种状态图片如下所示在自定义控件库项目上点击右键在弹出的快捷菜单选择“属性”在打开的属性页面中选择“资源”Tab页然后在右侧点击“创建或打开程序集资源”如下图所示点击“创建或打开程序集资源”会在项目的Properties目录中创建Resources.resx文件如下所示打开Resources.resx文件然后将图片添加为资源这样图片就可以作为自定义控件库的资源如下所示2. 创建扩展控件选择控件库然后点击右键在弹出的快捷菜单中选择“添加”然后选择“新建项(W)...”在弹出的“添加新项”对话框中选择“自定义控件(Windows窗体)”然后输入名称点击“添加”按钮即可如下图所示在本实例中创建两个自定义控件分别命名为“ToggleSwitch”和“ToggleLight”分别表示开关控件和灯泡如下所示打开创建的扩展控件的代码视图然后修改控件的继承类默认为Control修改为需要扩展的控件类如ButtonCheckBox等。ToggleSwitch开关控件派生自CheckBox具备CheckBox的所有功能如下所示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表单中如下所示为ToggleSwitch控件添加Click事件如下所示当鼠标点击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; } } }运行示例运行示例当点击开关控件时灯泡也会同时改变效果效果如下所示以上就是《基于.NET的Windows窗体编程之WinForms自定义控件(2)》的全部内容旨在抛砖引玉一起学习共同进步