因为我是电子专业的,学校没教过C#,学下来也基本上都是野路子东看西看基于需求地乱学,故而对C#的理解并不是很深。然而个人项目需要自定义一个控件来实现动态连线功能,不得不从入门直接跳到高级应用进行学习,这里做一个记录以对后面有类似需要的朋友一个参考。目前只是实现了一个简单的变色按钮功能,但是需要使用的大部分技术都用上了,如果需要实现其它更复杂功能的话就把本文当个抛砖引玉吧。
本文参考了《[C#] (原创)一步一步教你自定义控件——01,TrackBar》,但是在其基础上增加了设置控件区域的功能。另外因为那篇文章被很多人盗用,原文已经不可考,所以不贴地址给他们引流了,如果有需要可以直接百度这个名字即可。
新建工程
新建一个项目,选择Windows窗体控件库(.NET Framwork),然后选择地址、命名。
正常情况下工程里应该有一个UserControl1.cs文件,不要它,直接删除,然后新建一个没有模板的类。
将此类的访问属性改为public并且继承自Control,如果Control下出现波浪线报错的话是因为没有引用其命名空间,可以按住Alt + Enter
后选中第一个命名空间再按一次Enter进行修改,VS将自动添加上using System.Windows.Forms;
。
添加属性
然后我们根据需求进行添加属性,因为这个功能只是需要实现一个圆形开关,那么我们需要知道的属性就有开关打开时的颜色,开关关闭时的颜色,圆形开关的直径,开关的状态四个属性。颜色使用Color类进行定义,直径使用int或者float进行定义,开关状态用布尔进行定义,并且给他们赋值上初始值。
private Color openColor = Color.FromArgb(128, 255, 128); // 开启默认浅绿色
private Color closeColor = Color.FromArgb(255, 128, 128); // 关闭默认浅红色
private int diameter = 20; // 直径默认20,且为整数类型
private bool isOpen = false; // 默认关闭
然后为他们添加上各自的访问器:
我们可以注意到,他们各自的get访问器其实没啥特别的,但是set访问器中除了基本的赋值以外,每个访问器中都有Invalidate();
这么一句,它的工作目的是重新绘制一遍控件。
一般来说,如果你调整的这个属性将会影响到当前控件的外观,那么就有必要加上这么一句,它的功能类似于将原本的控件从你的屏幕上删除,然后根据新的定义创建一个新的控件。
然后我们再观察直径的访问器中使用了Size = new Size(diameter, diameter);
这么一句话,它的目的是什么呢?其实从语义上就可以推测知道,是重新赋值了大小属性,其中宽度和长度变成了直径的。但是理论上其实不加这句也没有问题,因为我们后面会使用一个指定边界函数实现相同功能,但是如果不加上的话我们在使用Winform的设计模式的时候就容易出现bug,调整大小的时候,如果调大就会出现内容消失的情况,需要手动去调整一下才能重新刷新出来。我理解的原因是设计模式其实开启了一个模拟窗口,但是这里我们修改属性值的时候只有一些基础属性会被显示出来而不会触发具体的方法函数。故而我们不能运行后面那个指定边界函数进行样式的刷新,导致出现视觉bug。
然后另一个需要注意的是,我们在IsOpen中使用了一个TestSwitch的事件,如果我们的开关状态发生了改变,那么就会触发这个事件。后来如果我们需要,可以为这个事件增加功能,一旦IsOpen被赋值,就可以执行相应的功能。
不过我们如果需要使用这个功能的话,就还需要添加上委托和事件的定义,一般情况下我们在命名空间内写委托,然后在类里定义事件。