首先创建一个新的项目,选c# --->windows控件库,namespace:TryGrid。 在class前加入[Designer(typeof(GridDesigner))]
接口方面 : Panel, ICellLabelManager 然后再建一个新的类,来写 ICellLabelManager。代码如下:
/// /// /// |
下面是msdn中的一段例子,有助于理解
Visual C# .NET 为您提供通过“继承”创建功能强大的自定义控件的能力。通过继承,您可以创建控件,这些控件不仅保留了标准 Windows 窗体控件的所有内在功能,并且还包含自定义功能。在本演练中,您将创建一个名为 ValueButton 的简单继承控件。此按钮将继承标准 Windows 窗体按钮的功能,并将公开一个名为 ButtonValue 的自定义属性。
创建新项目时,应指定其名称以便设置根命名空间、程序集名称和项目名称,并确保默认组件位于正确的命名空间中。
创建 ValueButtonLib 控件库和 ValueButton 控件
注意 “Windows 控件库”模板在 Visual C# .NET 的标准版中不可用。有关更多信息,请参见 Visual C# 标准版的功能。
默认情况下,项目名称 ValueButtonLib 也会分配到根命名空间中。根命名空间用于限定程序集中的组件名。例如,如果两个程序集都提供名为 ValueButton 的组件,则可以使用 ValueButtonLib.ValueButton
指定 ValueButton 组件。有关更多信息,请参见组件和程序集。
public class UserControl1
,将 UserControl1 更改为 ValueButton 以更改组件的名称。 请注意设计器将不再可用。因为 Button 控件进行它自己的绘制,您将无法在设计器中修改它的外观。除非在代码中进行修改,否则它的可视化表示形式将与它从中继承的类(即 Button)的可视化表示形式完全一样。
继承的 Windows 窗体控件的可能用途之一是创建与标准 Windows 窗体控件的外观相同、但公开自定义属性的控件。在本节中,您将向控件中添加名为 ButtonValue 的属性。
添加 Value 属性
// Creates the private variable that will store the value of your // property. private int varValue; // Declares the property. public int ButtonValue { // Sets the method for retrieving the value of your property. get { return varValue; } // Sets the method for setting the value of your property. set { varValue = value; } }
此代码设置存储和检索 ButtonValue 属性的方法。get 语句设置返回到存储在私有变量 varValue 中的值的值,set 语句通过使用 value 关键字设置私有变量的值。
控件不是独立的项目,它们必须寄宿在某个容器中。若要测试控件,必须提供一个运行该控件的测试项目。还必须通过生成(编译)该控件使其可由测试项目访问。在本节中,将生成控件并在 Windows 窗体中测试它。
生成控件
生成应该成功,没有任何编译器错误或警告。
创建测试项目
添加引用后,应将新控件添加到工具箱。如果您的控件已经出现在工具箱中,则应该跳过下一节。
将控件添加到工具箱
“自定义工具箱”对话框打开。
ValueButton 出现在“自定义工具箱”对话框的组件列表中。
ValueButton 被添加到选定的工具箱的选项卡上。
将控件添加到窗体
窗体上显示一个“ValueButton”。
代码编辑器打开并显示 valueButton1_Click 事件。
label1.Text = valueButton1.ButtonValue.ToString();
出现 Form1。
Label1 中显示数字“5”,说明继承控件的 ButtonValue 属性已经通过 ValueButton1_Click 方法传递到 Label1。这样,ValueButton 控件便继承了标准 Windows 窗体按钮的所有功能,但是公开了一个附加的自定义属性
http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/vbcon/html/vbconcontrolpaintingrendering.asp
用户控件提供了一种创建和重用自定义图形界面的方法。用户控件本质上是具有可视化表示形式的组件。因此,它可能包含一个或多个 Windows 窗体控件、组件或代码块,它们能够通过验证用户输入、修改显示属性或执行作者所需的其他任务来扩展功能。可以按照与其他控件相同的方式,将用户控件置于 Windows 窗体中。在本演练的第一部分,创建一个名为 ctlClock 的简单用户控件。在本演练的第二部分通过继承扩展 ctlClock 的功能。
创建新的项目时应指定其名称,以设置根命名空间、程序集名称和项目名称,并确保默认组件将位于正确的命名空间中。
创建 ctlClockLib 控件库和 ctlClock 控件
注意 “Windows 控件库”模板在 Visual C# .NET 的标准版中不可用。有关更多信息,请参见 Visual C# 标准版的功能。
默认情况下,项目名称 ctlClockLib 也被分配到根命名空间中。根命名空间用于限定程序集中的组件名。例如,如果两个程序集都提供名为 ctlClock 的组件,则可以使用 ctlClockLib.ctlClock
指定 ctlClock 组件。在解决方案资源管理器中,右击“UserControl1”并从快捷菜单中选择“查看代码”。
public class UserControl1
,将 UserControl1 更改为 ctlClock 以更改组件的名称。
注意 默认情况下,用户控件从系统提供的 UserControl 类继承。 UserControl 类提供所有用户控件要求的功能,并实现标准方法和属性。
可视化界面是用户控件的基本部分。这种可视化界面是通过将一个或多个 Windows 控件添加到“用户控件设计器”中实现的。在下面的演示中,将向用户控件中加入 Windows 控件,并编写代码以实现功能。
将标签和计时器添加到用户控件中
名为 label1 的标签控件被添加到用户控件设计器上的控件中。
属性 | 更改为 |
---|---|
Name | lblDisplay |
Text | (空白) |
TextAlign | MiddleCenter |
Font.Size | 14 |
因为计时器是个组件,所以它在运行时没有可视化的表示形式。因此,它不与其他控件一起出现在“用户控件设计器”上,而是出现在组件栏中。
Interval 属性控制计时器组件的刻度频率。timer1 每走过一个刻度,它都会运行一次 Timer1_Tick 事件中的代码。interval 表示前后两次刻度之间的毫秒数。
protected void timer1_Tick(object sender, System.EventArgs e) { // Causes the label to display the current time lblDisplay.Text = DateTime.Now.ToLongTimeString(); }
这些代码将使得当前时间显示在 lblDisplay 中。因为 timer1 的间隔设置为 1000,所以该事件每隔 1000 毫秒激发一次,从而每隔一秒就更新一次当前时间。
protected virtual void timer1_Tick(object sender, System.EventArgs e)
现在,clock 控件封装了 Label 控件和 Timer 组件,每个都有其自己的继承属性组。尽管您的控件的后续用户无法访问这些控件的个别属性,但可以通过编写适当的代码块来创建和公开自定义属性。在下面的章节中,您将向控件中添加属性,这些属性使用户能够更改背景和文本的颜色。
将属性添加到用户控件中
控件的代码编辑器打开。
private Color colFColor; private Color colBColor;
这些语句会创建私有变量,用来存储要创建的属性的值。
// Declares the name and type of the property. public Color ClockBackColor // Retrieves the value of the private variable colBColor. { get { return colBColor; } // Stores the selected value in the private variable colBColor, and // updates the backcolor of the label control lblDisplay. set { colBColor = value; lblDisplay.BackColor = colBColor; } } // Provides a similar set of instructions for the forecolor. public Color ClockForeColor { get { return colFColor; } set { colFColor = value; lblDisplay.ForeColor = colFColor; } }
前述的代码使两个自定义属性(ClockForeColor 和 ClockBackColor)可用于该控件后面的用户。Get 和 Set 语句提供属性值的存储和检索,以及提供实现适合于属性的功能的代码。
控件不是独立的应用程序,它们必须寄宿在容器中。为了测试控件,必须提供一个在其中运行该控件的测试项目。在本节中,将生成控件并在 Windows 窗体中测试它。
生成控件
创建测试项目
注意,此时该项目显示在“选定的组件”窗口中。
在添加引用之后,可以将控件置于您的窗体中。
测试控件
现在,您的控件的副本被添加到窗体中。请注意,它显示当前时间,并且每秒更新一次。
控件的另一个副本被拖放到窗体上。可以根据需要将任意数目的计时器副本添加到您的窗体上。
该实例的属性显示在“属性”窗口中。
控件的背景颜色更改为您选择的颜色。
在本节中,您已经知道组件和 Windows 控件如何与代码和打包结合,以用户控件的形式提供自定义功能。您已经学会在用户控件中公开属性,以及如何在完成后测试控件。在下一节中,您将学习如何将 ctlClock 用作基来构造继承的用户控件。
在上一节中,您已经学会如何将 Windows 控件、组件和代码组合成可重用的用户控件。现在,您的用户控件可以用作生成其他控件的基础。从基类派生类的过程称为“继承”。在本节中,将创建称为 ctlAlarmClock 的用户控件。此控件将从其父控件 ctlClock 中派生。您将学习通过重写父级方法并添加新的方法和属性来扩展 ctlClock 的功能。
创建继承控件的第一步是从它的父控件派生。该操作创建一个新控件,它具有父控件的全部属性、方法和图形特征,但也可以用作添加新功能或修改过的功能的基础。
创建继承的控件
“添加新项”窗口打开,这时“继承的用户控件”已选中。
“继承选择器”窗口出现。
将属性添加到继承的控件的方法与添加到用户控件的方法相同。现在将使用属性声明语法向控件中添加两个属性:AlarmTime 和 AlarmSet,前者将存储发出警报的日期和时间值,后者将指示是否设置了警报。
将属性添加到用户控件中
private DateTime dteAlarmTime; private bool blnAlarmSet; // These properties will be declared as public to allow future // developers to access them. public DateTime AlarmTime { get { return dteAlarmTime; } set { dteAlarmTime = value; } } public bool AlarmSet { get { return blnAlarmSet; } set { blnAlarmSet = value; } }
继承的控件具有可视化的界面,该界面与它从中继承的控件的界面完全相同。它与其父控件拥有相同的构成控件,但除非将构成控件的属性特别公开,否则它们将不可用。可以向继承的用户控件的图形界面进行添加,方法与向任何用户控件进行添加时相同。若要继续向您的警报时钟的可视化界面进行添加,请您添加一个 label 控件,它将在警报响起时闪烁。
添加 label 控件
ctlAlarmClock 的设计器在主窗口中打开。
注意,当显示所有属性时,属性是浅灰色的。这表明这些属性是 lblDisplay 所固有的,因而不能在属性窗口中修改或访问。默认情况下,包含在用户控件中的控件是 private,其属性无论如何都无法访问。
提示 如果希望用户控件后面的用户可以访问其内部控件,则将其声明为 public 或 protected。这样就可以使用适当的代码,设置和修改包含在用户控件内的控件的属性。
属性 | 设置 |
---|---|
Name | lblAlarm |
Text | Alarm! |
TextAlign | Middle Center |
Visible | false |
在前面的章节中,已经添加了一些属性和一个控件,它们将启用用户控件中的警报功能。在本节中,将添加代码以比较当前时间和警报时间,如果两者相同,则警报会闪烁。通过重写 ctlClock 的 Timer1_Tick 方法并将其他的代码添加到其中,可以在扩展 ctlAlarmClock 功能的同时仍保留 ctlClock 的固有功能。
重写 ctlClock 的 timer1_Tick 方法
private bool blnAlarmSet;
语句。在它之后,紧接着添加下列语句: private bool blnColorTicker;
protected override void timer1_Tick(object sender, System.EventArgs e) { // Calls the Timer1_Tick method of ctlClock. base.timer1_Tick(sender, e); // Checks to see if the Alarm is set. if (AlarmSet == false) return; else // If the date, hour and minute of the alarm time are the same as // now, flash! { if (AlarmTime.Date == DateTime.Now.Date && AlarmTime.Hour == DateTime.Now.Hour && AlarmTime.Minute == DateTime.Now.Minute) { // Makes lblAlarmVisible, and changes the backcolor based on // the value of blnColorTicker. The backcolor of the label // will flash once per tick of the clock. lblAlarm.Visible = true; if (blnColorTicker == false) { lblAlarm.BackColor = Color.Red; blnColorTicker = true; } else { lblAlarm.BackColor = Color.Blue; blnColorTicker = false; } } else { // Once the alarm has sounded for a minute, the label is made // invisible again. lblAlarm.Visible = false; } } }
添加此代码将完成几项任务。Override 语句指示控件使用此方法替换从基控件继承的方法。此方法被调用时,它通过调用 base.timer1_Tick 语句来调用它重写的方法,从而确保在该控件中重新产生原始控件包含的所有功能。然后,它运行附加代码以合并警报功能。当触发警报时,闪烁的 label 控件将出现。
警报时钟控件已经基本完成。剩下的唯一事情是实现关闭它的方法。为此,将向 lblAlarm_Click 方法中添加代码。
实现关闭方法
设计器打开。
属性 | 值 |
---|---|
Name | btnAlarmOff |
Text | Disable Alarm |
代码编辑器打开并显示 private void btnAlarmOff_Click 行。
private void btnAlarmOff_Click(object sender, System.EventArgs e) { // Turns off the alarm AlarmSet = false; // Hides the flashing label lblAlarm.Visible = false; }
与标准用户控件一样,继承的用户控件不能独立存在,而必须寄宿在窗体或其他容器中。由于 ctlAlarmClock 的功能更加深入,因此需要附加代码以对其进行测试。在本节中,将编写一个简单的程序来测试 ctlAlarmClock 的功能。将编写代码以设置和显示 ctlAlarmClock 的 AlarmTime 属性,而且将测试其继承功能。
生成一个测试窗体并将您的控件添加到该窗体
控件 | 属性 | 值 |
---|---|---|
label1 | Text | (保留为空白) |
Name | lblTest | |
dateTimePicker1 | Name | dtpTest |
Format | Time |
代码编辑器打开并显示 private void dtpTest_ValueChanged
。
private void dtpTest_ValueChanged(object sender, System.EventArgs e) { ctlAlarmClock1.AlarmTime = dtpTest.Value; ctlAlarmClock1.AlarmSet = true; lblTest.Text = "Alarm Time is " + ctlAlarmClock1.AlarmTime.ToShortTimeString(); }
测试程序启动。注意,当前时间在 ctlAlarmClock 控件中被更新,并且启动时间显示在 DateTimePicker 控件中。
警报设置的时间显示在 lblTest 中。
当显示时间到达设置警报的时间时,lblAlarm 将会闪烁。单击 btnAlarmOff 关闭警报。您现在可以重置警报。
本演练涉及了一些关键概念。您已经学会通过将控件和组件组合到用户控件容器中来创建用户控件。您还已经学会将属性添加到控件,以及编写代码以实现自定义功能。在第二节中,您学会了通过继承来扩展给定用户控件的功能,以及通过重写这些方法来更改宿主方法的功能。
原来添加一个属性是很简单的事情,弄个变量,在写个get set就完了^_^