首先,创建设计期库,步骤如下:
1.
“新建
->
项目
->
类库”,取名
XxxDesigner
,如图。注意将项目放在
Xxx
目录下。

2.
修改项目属性,将默认命名空间改为
Xxx
(当然也可以使用其他名字,只要与运行期库一致即可),如图

3.
打开
AssemblyInfo.cs
文件,改变程序集版本号,即将
[assembly: AssemblyVersion("1.0.*")]
改为某个特定的值,比如
[assembly: AssemblyVersion("1.2.3.4")]
4.
修改引用:移除原来的所有引用,依次加入如下程序集。注意加入的次序很重要,必须按照以下顺序:
/r:"E:/Microsoft Visual Studio .NET 2003/CompactFrameworkSDK/v1.0.5000/Windows CE/Designer/System.CF.Design.dll"
/r:"E:/Microsoft Visual Studio .NET 2003/CompactFrameworkSDK/v1.0.5000/Windows CE/Designer/System.CF.Windows.Forms.dll"
/r:"E:/Microsoft Visual Studio .NET 2003/CompactFrameworkSDK/v1.0.5000/Windows CE/Designer/System.CF.Drawing.DLL"
/r:System.Windows.Forms.dll
/r:System.Drawing.DLL
/r:System.dll
引用程序集添加完成后,项目解决方案如图(注意:“引用”中的显示的程序集依字母顺序排列,与添加顺序无关):

5.
修改“项目属性
->
配置属性
->
生成”,取消显示特定警告
1595
(当两个引用程序集中含有名字和命名空间都完全相同的类,且项目使用了这个类时,就会引起该警告,此时实际使用哪个类依引用程序集时的添加顺序为准,使用先添加的那一个),如图:

6.
“添加
->
添加新项
->
用户界面
->
自定义控件
”
,删除原来的类文件。
7.
对
VS.NET
生成的自定义组件代码模板,删去
using
System.Data;
,
删去
components
变量,删去
InitializeComponent
方法中对
components
的初始化以及
Dispose
方法中对
components
的使用(否则如果对组件添加了
Timer
这样的资源会引起编译错误,错误原因是在
System.CF.Windows.Forms
程序集中的
Timer
没有带参的构造函数,与
System.Windows.Forms
程序集中的
Timer
不同)。对
Dispose
方法,如果使用了像
Timer
这样的资源,则必须在其中调用
Timer
的
Dispose
方法(注意运行期库中不需要
Dispose
方法)。
8.
为组件添加一个图标,这个图标在组件被选择放入工具箱以备使用时显示。添加图标方法如下:首先,为
XxxDesigner
项目添加一个位图资源文件,注意该位图文件的取名要与相应组件完全一致(例如组件名为
CustomControl1
,则位图文件名为
CustomControl1.bmp
);然后改变其“属性
->
高级
->
生成操作”,改为“嵌入的资源”;再调整位图大小,改为
16
×
16
;最后,为组件所在类添加
ToolboxBitmap
特性,如下:
[ToolboxBitmap(typeof(ClassLibrary.CustomControl1), "CustomControl1.bmp")]
9.
通过
Designer
特性为组件添加一个设计器,如下:
[Designer(typeof(System.Windows.Forms.Design.ControlDesigner))]
如果组件仅需要一般的设计期行为,则使用
ControlDesigner
已足够,否则需要自定义设计器,大致方法是从
ControlDesigner
派生一个新的设计器然后通过
Designer
特性指派给相应组件,在此不详细叙述。
10.
重载组件相应的函数,完成自定义组件的相应要求(如重载OnPaint函数自定义组件的绘制行为,等等等等)。
11.
经过以上步骤,代码框架如下:
using
System;
using
System.Collections;
using
System.ComponentModel;
using
System.Drawing;
using
System.Windows.Forms;
[assembly: System.CF.Design.RuntimeAssembly("ClassLibraryRuntime, Version=1.2.3.4, Culture=neutral, PublicKeyToken=null")]
namespace
ClassLibrary
{
///<summary>
/// CustomControl1
的摘要说明。
///</summary>
[ToolboxBitmap(typeof(ClassLibrary.CustomControl1), "CustomControl1.bmp") , Designer(typeof(System.Windows.Forms.Design.ControlDesigner))]
public class CustomControl1 : System.Windows.Forms.Control
{
private System.Windows.Forms.Timer timer1;
public CustomControl1()
{
//
该调用是 Windows.Forms 窗体设计器所必需的。
InitializeComponent();
// TODO:
在 InitComponent 调用后添加任何初始化
}
///<summary>
///
清理所有正在使用的资源。
///</summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
timer1.Dispose() ;
}
base.Dispose( disposing );
}
#region
组件设计器生成的代码
///<summary>
///
设计器支持所需的方法 - 不要使用代码编辑器
///
修改此方法的内容。
///</summary>
private void InitializeComponent()
{
this.timer1 = new System.Windows.Forms.Timer();
}
#endregion
protected override void OnPaint(PaintEventArgs pe)
{
// TODO:
在此添加自定义绘画代码
//
调用基类 OnPaint
base.OnPaint(pe);
}
}
}
解决方案如图:

然后,创建运行期库,步骤如下:
1.
在同一个解决方案中,选择“添加
->
新建项目
->
智能设备应用程序”,取名为
XxxRuntime
,放置在
Xxx
目录下,如图

点击确定后,平台选择:
WinCE
,项目类型选择:类库。
2.
修改项目属性,将其默认命名空间改为与设计期库一致。
3.
打开
AssemblyInfo.cs
文件,修改程序集版本号,即将
[assembly: AssemblyVersion("1.0.*")]
改为某个特定的值,比如
[assembly: AssemblyVersion("1.2.3.4")]
。
注意对于版本号,设计期库和运行期库最好保持一致的。
4.
为运行期项目添加引用,如下:
/r:"E:/Microsoft Visual Studio .NET 2003/CompactFrameworkSDK/v1.0.5000/Windows CE /System.Windows.Forms.dll"
/r:"E:/Microsoft Visual Studio .NET 2003/CompactFrameworkSDK/v1.0.5000/Windows CE /System.Drawing.DLL"
5.
修改设计期库,在它的命名空间之外为其加上
RuntimeAssembly
特性,如下:
[assembly: System.CF.Design.RuntimeAssembly("ClassLibraryRuntime, Version=1.2.3.4, Culture=neutral, PublicKeyToken=null")]
注意
RuntimeAssembly
特性是CF特有的,对于创建一个自定义组件库非常重要,正是通过这个特性将设计期库和运行期库联系起来。
6.
删除原有类文件,向运行期库添加新的类文件,作为设计期组件对应的运行期组件,注意文件取名要与设计期库中相应组件完全一致;然后将设计库的代码适当拷贝过来(注意是适当拷贝,不是完全拷贝,因为设计期和运行期毕竟会有一些不同,它们有一些行为并不完全一致,故代码有时也不是完全相同的,比如运行期组件就不需要
Dispose
方法等等;但注意应尽量保持两者的一致或者至少对应)
7.
经过以上步骤,代码框架如下:
using
System;
using
System.Collections;
using
System.ComponentModel;
using
System.Drawing;
using
System.Windows.Forms;
namespace
ClassLibrary
{
///<summary>
/// CustomControl1
的摘要说明。
///</summary>
public class CustomControl1 : System.Windows.Forms.Control
{
private System.Windows.Forms.Timer timer1;
public CustomControl1()
{
//
该调用是 Windows.Forms 窗体设计器所必需的。
InitializeComponent();
// TODO:
在 InitComponent 调用后添加任何初始化
}
#region
组件设计器生成的代码
///<summary>
///
设计器支持所需的方法 - 不要使用代码编辑器
///
修改此方法的内容。
///</summary>
private void InitializeComponent()
{
this.timer1 = new System.Windows.Forms.Timer();
}
#endregion
protected override void OnPaint(PaintEventArgs pe)
{
// TODO:
在此添加自定义绘画代码
//
调用基类 OnPaint
base.OnPaint(pe);
}
}
}
解决方案如图:

自定义控件的使用:
1.
将
Designer
目录最终生成的
DLL
文件拷贝到
E:/Microsoft Visual Studio .NET 2003/CompactFrameworkSDK/v1.0.5000/Windows CE/Designer
目录下
2.
将
Runtime
目录下最终生成的
DLL
文件拷贝到
E:/Microsoft Visual Studio .NET 2003/CompactFrameworkSDK/v1.0.5000/Windows CE
目录下
3.
新建一个智能设备引用程序,平台选择:
WinCE
,项目类型选择:
Windows
应用程序。
4.
在窗体设计器中,在“工具箱”的“设备控件”选项卡右击,选择“添加
/
移除项”,出现如图对话框,浏览到
E:/Microsoft Visual Studio .NET 2003/CompactFrameworkSDK/v1.0.5000/Windows CE/Designer
目录,选择
XxxDesigner.dll
文件。

5.
点击确定后,自定义控件就放在工具箱中,可以像标准控件一样使用了。