内容提要
本文介绍如何用Visual C# NET 开发简单的复合控件(Composite Control)主要讲解控件开发过程中的属性(Property)和事件(Event)处理以方便开发人员在NET平台下根据自己的需要开发适合的控件
当我们在NET平台下做Windows Forms开发时常常需要为了某一特殊用途而把现有控件结合起来使用比如结合了Label和TextBox的控件就非常容易在窗体上布局(记得Delphi 里就有这么个控件)而结合了特定图案和文字的控件则非常适合显示公司的logoNET平台就为我们提供了非常棒的工具和技术来创建这样的自定义控件下面让我们来一起创作一个可以自动显示时间的控件
值得注意的是NET平台为我们提供了三种控件的开发技术分别是继承控件(Extended Control)复合控件(Composite Control)和自定义控件(Custom Control)(译名可能会有所不同大家可以以英文为准)我们现在关心的是第二种——复合控件OKLets go!
.创建控件工程
在Visual C# NET中新建一个Windows控件库项目命名为TimeLabel
.更改命名空间控件类名称
默认的命名空间是TimeLabel(和项目名称一样)控件类名称是UserControl请把命名空间改为与你的开发习惯一致如我的是LeoYangControlsTimeLabel当然你也可以选择保留默认命名空间最好把控件类名称改为有意义的命名如TimeLabel这样当该控件出现在工具箱上时就会显示为TimeLabel而不是UserControl了注意一旦改动类名则相应的Construction方法名称也要相应改掉如
public UserControl()
{
…
}
就要改为
public TimeLabel()
{
…
}
.添加现有控件
由于我们是要在现有控件的基础上创建新控件所以就应该先把可用的现有控件添加到控件设计界面上请在工具箱中双击Label再双击Timer两个现有控件依次被添加到我们的设计界面上如图
.公布控件属性
因为要把时间写入Label的Text属性中所以我们需要把labelText属性公开请在TimeLabel类中加入以下代码
public string LabelText
{
get
{
return labelText;
}
}
注意这里我们不需要让控件使用者改变labelText的值所以LabelText是个只读属性
另外出于美观的考虑我们这里还要向控件使用者公开一个LabelBackColor属性用于获得和设置Label的BackColor属性代码如下
public Color LabelBackColor
{
get
{
return labelBackColor;
}
set
{
labelBackColor=value;
}
}
当然你也可以根据需要再增加一些属性如字体控件大小等让控件使用者可以更加灵活地使用控件
到这里我需要向大家补充一点复合控件创建中的很重要的一条是任何构成控件(Constituent Control)的属性必须要通过加入复合控件的属性来公开而不要直接把构成控件直接以public级别公开比如说上面我们就不应把Label控件的访问级别设为public来直接公开(默认是private)这样作的目的是让我们能更好地把握控件的数据安全从而只把那些最需要的属性公开给控件用户
.时间显示的处理
到现在我们就可以增加代码来让我们的控件显示时间了首先请把timer的Interval属性设为也就是秒的时隔然后双击timer在其Tick事件处理过程中增加以下代码
labelText=SystemDateTimeNowToLongTimeString();
这样每隔一秒钟我们的Label就会重新显示当前系统时间最后请双击TimeLabel控件上的空白处在出现的TimeLabel_Load事件处理过程中增加以下代码来激活Timer
timerEnabled=true;
这样Timer就会忠心耿耿地开始计算时间并更新Label上的时间文字了
.事件处理
由于是继承自UserControl的控件所以TimeLabel从一开始便拥有了ClickDragDropFontChanged等事件我们现在要做的是增加一个自定义事件——Tick以便通知使用我们控件的窗体时间已经改变了因为我们只需要简简单单地让这个事件发生所以不需创建我们自己的代理(delegate)函数也不需创建特殊的事件处理事据对象OK请看下面的代码
首先在TimeLabel类里增加Tick事件声明
public event EventHandler Tick;
然后给该事件编写一个调用过程请注意该过程的命名
protected void OnTick (EventArgs e)
{
if(Tick!=null)
{
Tick(this e);
}
}
另外在上面处理过的Timer的Tick事件处理过程中还应增加对OnTick的调用代码如下
private void timer_Tick(object sender SystemEventArgs e)
{
labelText=SystemDateTimeNowToLongTimeString();
OnTick(e);
}
.创建试验项目
在Visual C# NET中通过文件-添加项目-新建项目创建一个新的Windows应用程序命名为TestTimeLabel并添入当前解决方案中如图
.添加控件引用
在使用自定义控件之前我们必须把控件添加到工具箱中方法是右击工具箱点选自定义工具箱在弹出的自定义工具箱对话框中选择NET框架组件页然后点击浏览定位并打开我们刚才所创建的TimeLabel控件专有程序集(TimeLabeldll)使该控件出现在NET框架组件列表中如图所示
点击确定即可把TimeLabel控件添加到工具箱中如图所示
.使用控件
现在我们就可以把我们创建的TimeLabel像其它控件一样拖放到Windows窗体上设置它的属性和响应它的事件了比如可以在属性窗口中设置TimeLabel的LabelBackColor为你喜欢的颜色当然除LabelBackColor以外还有大量的属性可供设置而且如果大家愿意还可以回到TimeLabel项目中再用上面说过的方法增加其它的属性从而使控件功能和用户界面更加丰富
.响应事件
前面我们给TimeLabel增加了一个Tick事件每当时间显示改变之后发生那么我们的程序怎样知道Tick事件已经发生并对它做出反应呢?方法如下
首先增加事件处理过程如下(名称可以自定但必须要有object和EventArgs类型的参数并且以void类型返回)
private void TickHandler(object sender EventArgs e)
{
SystemDiagnosticsDebugWriteLine(timeLabelLabelText);
}
其次在FormInitializeComponent过程中把上述过程注册给TimeLabel的Tick事件
thistimeLabelTick+=new EventHandler(thisTickHandler);
这样我们的试验项目就已经完成可以调试了试验程序启动界面如图
同时在调试器的输出窗口中每隔一秒都会有一条新的Debug记录写入内容是TimeLabel的LabelText属性(即所显示的时间)这说明我们的事件处理成功了)
后记本文通过一个简单的demo演示了如何使用Visual C# NET创建一个简单的复合控件大家可以按照项目或学习的实际需要来把这个例子进一步完善(比如说可以给控件增加自定义的图标等)