You want to create a class that has basic design-time support and can be added to a form's component at design-time.
Derive your class from System.ComponentModel.Component .
The .NET class library includes many classes that can be added to a form, Web page, or another type of component at design time. For example, as shown in Figure 4-1, you can add the System.Windows.Forms.Timer object class directly to the component tray of a form, even though it has no visual representation. This allows the programmer to configure properties and connect event handlers at design time.
Figure 4-1:
A component object in the component tray.
To create a class that supports design-time creation, you must implement the
IComponent
interface. You can do this directly, or indirectly by deriving from
System.ComponentModel.Component
or
System.ComponentModel.MarshalByValueComponent
. The former is used for classes that may be
Once you derive from the component class, you need to add a small amount of
Here's a bare-bones example of a component class:
Public Class MyComponent Inherits System.ComponentModel.Component Protected Overloads Overrides Sub Dispose(disposing As Boolean) If disposing Then ' Disposal was triggered manually by the client. ' Call Dispose() on any contained classes. End If ' Release unmanaged resources. ' Set large membervariables to Nothing (null). ' Call Dispose on the base class. MyBase.Dispose(disposing) End Sub End Class
You should create component classes in a dedicated class library assembly. Once you have compiled the assembly, you can add the component classes to the Toolbox. Simply right-click the Toolbox, choose Add/Remove Items, and select the appropriate assembly. All component classes in the assembly will appear in the Toolbox and can now be dragged and dropped into the component tray (at which point a reference will be added to the assembly in your project). Figure 4-2 shows an example that includes two new
Figure 4-2:
Component objects in the Toolbox.
| Note |
The System.ComponentModel namespace includes many attributes you can use to decorate the properties of a component class and influence how they will appear in the Properties window. For example, you can use DescriptionAttribute to add a text description that will appear in the window, DefaultValueAttribute to specify the initial value, DefaultPropertyAttribute to configure which property will be initially selected when the control receives focus at design-time, and so on. |
You want to create a class that can be converted to common data types such as Int32 and String .
Implement the IConvertible interface. Add conversion code for the supported data types, and throw an InvalidCastException for all unsupported data types.
The
IConvertible
interface defines 17
Public Function GetTypeCode() As TypeCode _ Implements IConvertible.GetTypeCode Return TypeCode.Object End Function
The other 16 methods perform the actual conversions and begin with the word To , as in ToBoolean , ToByte , ToString , and so on. If a method doesn't apply to your object, simply throw an InvalidCastException in the method.
Here's a partial example with a complex number class:
Public Class ComplexNumber Implements IConvertible Private _Real As Double Private _Imaginary As Double Public Property Real() As Double Get Return _Real End Get Set(ByVal Value As Double) _Real = Value End Set End Property Public Property Imaginary() As Double Get Return _Imaginary End Get Set(ByVal Value As Double) _Imaginary = Value End Set End Property Public Function GetModulus() As Double Return Math.Sqrt(Me.Real ^ 2 + Me.Imaginary ^ 2) End Function Public Function ToBoolean(ByVal provider As System.IFormatProvider) _ As Boolean Implements System.IConvertible.ToBoolean Throw New InvalidCastException End Function Public Function ToDateTime(ByVal provider As System.IFormatProvider) _ As Date Implements System.IConvertible.ToDateTime Throw New InvalidCastException End Function Public Function ToDecimal(ByVal provider As System.IFormatProvider) _ As Decimal Implements System.IConvertible.ToDecimal Return CType(GetModulus(), Decimal) End Function Public Function ToDouble(ByVal provider As System.IFormatProvider) _ As Double Implements System.IConvertible.ToDouble Return GetModulus() End Function ' (Other conversion methods omitted.) End Class
To perform a conversion, a client can call a conversion method directly or use the System.Convert class, which works with any IConvertible object.
Dim MyDouble As Double = Convert.ToDouble(MyComplexNumber)
In addition,
IConvertible
allows your object to work with some batch conversions. For example, you can use the
ArrayList.ToArray
method to create a strongly typed array if your
ArrayList
contains the same type of object, and this type of object implements
IConvertible
. Recipe 3.7