65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 C# 和 .NET SDK 创建控件

2000 年 10 月 18 日

viewsIcon

233813

downloadIcon

1731

创建第一个 C# 控件的快速入门指南。

  • 下载演示项目 - 8 Kb
  • 引言

    在本教程中,我将创建一个简单的时钟控件来演示如何使用 .NET 框架。 该控件将是一个显示当前时间的时钟,我将留给读者实现秒针并绘制时钟数字。

    本教程重点介绍了创建控件的主要要点。 读者应参考随附的源代码以获取更多详细信息。 从头开始创建控件的最快方法是复制以下控件示例:

    ..\Program Files\NGWSSDK\Samples\QuickStart\winforms\samples\Cs\WritingControls\helloworldcontrol

    将此目录复制到另一个名为 MyControl 的目录

    ..\Program Files\NGWSSDK\Samples\QuickStart\winforms\samples\Cs\WritingControls\MyControl

    重命名并编辑此目录中的文件,将引用从 helloworldcontrol 更改为 myControl

    • Helloworldcontrol.cs -> mycontrol.cs
    • Helloworldcontrol.src -> mycontrol.src * 还不清楚这个文件是干什么的

    编辑这些文件并将引用从 helloworldcontrol 更改为 myControl

    • Hostapp.cs
    • Makefile

    打开一个控制台窗口并键入 NMAKE ALL。 期望会生成两个文件

    • MyControl.exe - 托管控件的应用程序
    • MyControl.DLL - 实际的控件。

    现在,基本/骨架/样板代码已经创建,我们可以通过运行 mycontrol.exe 来测试它。

    我们现在可以开始设计我们的控件。

    1. 我们需要添加我们将要使用的任何命名空间。 命名空间包含我们在控件中引用的类

      using System.ComponentModel;          // Needed for control support
      using System.Timers;                  // Needed to support timer
      using System.Runtime.InteropServices; // Needed for StructLayout attribute 
      

    2. 下一步是包含 C# 的一些扩展功能,这些功能允许调用 Windows 操作系统。 我已经包含了这些定义,因为我找不到一个类似的功能来获取系统时间。

      // Definition of WINAPI SYSTEMTIME structure 
      [StructLayout(LayoutKind.Sequential)]
      public class SystemTime {
      	public ushort wYear;
      	public ushort wMonth;
      	public ushort wDayOfWeek;
      	public ushort wDay;
      	public ushort wHour;
      	public ushort wMinute;
      	public ushort wSecond;
      	public ushort wMilliseconds;
      }
      
      // Definition of WINAPI GetLocalTime function[DllImport("Kernel32.dll")]
      public static extern void GetLocalTime(SystemTime st);
      
    3. 现在我们声明将在对象生命周期中使用的成员变量
      private Colorm_colorHands;private Colorm_colorFace;
      private boolm_bActivateClock;
      private System.Timers.Timer	m_timer;
      

      请注意,与 C++ 不同,C++ 在每个变量声明之前都包含可访问性关键字,而可访问性关键字定义了变量块。

    4. 现在声明构造函数。

      像 Java 一样,方法是内联编码的。 这需要一段时间才能习惯,但从长远来看,这使编辑变得容易得多。

      public MyControl() {
      	m_colorHands = Color.White;
      	m_colorFace = Color.Blue;
      	SetStyle(ControlStyles.Opaque, false);
      	SetStyle(ControlStyles.ResizeRedraw, true);
      }
    5. 下一步是定义要暴露给外部世界的任何属性。 这里包含的新功能是属性标签,它向其他子系统提供运行时信息。

      [
      Category("Clock"),
      Description("Hands color for Clock"),
      DefaultValue(0xFFFFFF),
      ]
      public Color HandsColor {
      	get {
      		return m_colorHands;
      	}
      
      	set {
      		m_colorHands = value;
      		Invalidate();
      		Update();	
      	}
      }

      方括号 [ ] 之间的代码声明属性限定符。 getset 方法对对象外部是透明的。 要修改时钟指针的颜色,您可以执行以下操作

      someobj.HandColor = Color.Red;

      set 方法需要一个隐式的 value 变量。

    6. 重写基类方法

      protected override void OnPaint(PaintEventArgs pe) {
      	// Let base class draw its stuff first
      	base.OnPaint(pe);
      
      	// Draw code here...
      }

      请注意这里的 override 关键字,它只是重写了一个基类函数。

      此代码调用基类对 OnPaint 的实现(base.OnPaint(pe);

    代码中其他值得注意的点是,对象是在堆上创建的。 与 C++ 不同,这些不需要 delete 运算符。 .NET 框架垃圾回收使用 new 运算符实例化的对象。

    例如。

    {
    	// ... Some code
    	SolidBrush brush = new SolidBrush(Color.White)
    
    	// Scope ends... no delete operator needed for brush
    }

    C# 的另一个特性是通过调用方法更改变量的值。

    请看下面的代码

    CalculatePoint(ptStart, out ptEnd,(st.wHour*5)+(st.wMinute/12), false, rc);

    请注意 override 关键字,它只是重写了一个基类函数。

    请注意 out 方法参数。 这声明了变量在传递到方法时已被修改。

    现在这是声明

    protected void CalculatePoint(Point pStart, out Point pEnd, 
                                  int nPos, bool bFlag, Rectangle rc)

    Mycontrol.exe 托管该控件。 测试该控件的另一种方法是运行 WinDes.exe,然后创建一个新的 C# Win32Form,然后选择“编辑/添加库”菜单项并选择 mycontrol.dll

    © . All rights reserved.