Creating a control with the .NET SDK using C#






1.57/5 (13 votes)
Oct 18, 2000

233484

1731
A quickstart guide to creating your first control in C#
Introduction
In this tutorial I'm going to create a simple clock control to demonstrate using the .NET framework. The control will be a clock showing the current time, and I'll leave it up to the reader to implement a second hand and draw the clock numerals.
This tutorial highlights the major points in creating a control. The reader should refer to the included source code for further details. The quickest method of creating a control from scratch is to copy one of the control samples from:
..\Program
Files\NGWSSDK\Samples\QuickStart\winforms\samples\Cs\WritingControls\helloworldcontrol
Copy this directory to another directory called MyControl
..\Program
Files\NGWSSDK\Samples\QuickStart\winforms\samples\Cs\WritingControls\MyControl
Rename and edit the files in this directory, change references from helloworldcontrol to myControl.
- Helloworldcontrol.cs -> mycontrol.cs
- Helloworldcontrol.src -> mycontrol.src * Dunno what this file is for yet
Edit these files and change references helloworldcontrol to myControl:
- Hostapp.cs
- Makefile
Open a console window and type NMAKE ALL. Hopefully two files will be produced:
- MyControl.exe - The application that hosts the control
- MyControl.DLL - The actual control.
Now the base/skeleton/boilerplate code has been created we can test it by running mycontrol.exe.
We can now start to engineer our control.
We need to add any namespaces we will be using. Namespaces contain the classes we will referencing in our control :
using System.ComponentModel; // Needed for control support using System.Timers; // Needed to support timer using System.Runtime.InteropServices; // Needed for StructLayout attribute
-
The next step is to include some extended features of C# which allows
calls to the Windows operating system. I've included these definition as I could not
find a similar function to obtain the system time.
// 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);
- Now we declare member variables that are going to be used during the lifetime of the object:
private Colorm_colorHands;private Colorm_colorFace; private boolm_bActivateClock; private System.Timers.Timer m_timer;
Notice here that the accessibility keyword is included in front of every variable declaration, unlike C++ where accessibility keywords define blocks of variables.
- Now declare the
constructor.
Like Java, methods are coded inline. This takes a bit of getting used to, but makes things a lot easier to edit in the long run.
public MyControl() { m_colorHands = Color.White; m_colorFace = Color.Blue; SetStyle(ControlStyles.Opaque, false); SetStyle(ControlStyles.ResizeRedraw, true); }
-
The next step is to define any properties which are going to be exposed
to the outside world. The new functionality included here is the attribute tag,
which gives runtime information to other subsystems.
[ Category("Clock"), Description("Hands color for Clock"), DefaultValue(0xFFFFFF), ] public Color HandsColor { get { return m_colorHands; } set { m_colorHands = value; Invalidate(); Update(); } }
The code between the [ ] brackets, declares the attribute qualifiers. The
get
andset
methods are transparent from outside of the object. To modify the the color of the clock hands you would do the followingsomeobj.HandColor = Color.Red;
The
set
method requires an implicit value variable. -
Overriding a base class method:
protected override void OnPaint(PaintEventArgs pe) { // Let base class draw its stuff first base.OnPaint(pe); // Draw code here... }
Notice here the
override
keyword, which simply overrides a base class function.This code calls the base class implementation of
OnPaint
(base.OnPaint(pe);
)
Other
points worth noting within the code are that objects are created on the heap. These
don't require the delete operator unlike C++. The .NET framework garbage collects objects
instantiated with the new
operator.
Eg.
{
// ... Some code
SolidBrush brush = new SolidBrush(Color.White)
// Scope ends... no delete operator needed for brush
}
Another feature of C# is the changing the value of variable by the calling method.
Look at the following code:
CalculatePoint(ptStart, out ptEnd,(st.wHour*5)+(st.wMinute/12), false, rc);
Note the override
keyword, which simply overrides a base class function.
Notice
the out
method parameter. This declares that the variable has been
modified when it was passed into a method.
Now here's the declaration:
protected void CalculatePoint(Point pStart, out Point pEnd,
int nPos, bool bFlag, Rectangle rc)
Mycontrol.exe hosts the control. Another way to test the control is to run WinDes.exe, then create a new C# Win32Form, then select the 'Edit/Add Library' menu item and select mycontrol.dll