|
Adding events to custom controls
The C# Column
We can also add properties and events to a custom control.
In the last two articles we saw how to create and use a clock control. In this
article we will add properties and an event to it.
The
idea is to modify the clock control to an alarm clock control. We plan to add
two propertiesAlarmTime and Message to the control. These properties can
be set or retrieved programmatically as well as through the Properties window.
The user can set the AlarmTime property to some specific time and as soon as
the specified time is reached, a message gets displayed. The user can specify
the message to be displayed through the Message property. The form data membersaltime
(of type DateTime) and almessage (of type string)are controlled by these
properties. We have added an event called alarm that would be fired as soon
as specified AlarmTime is reached. The AlarmTime and Message properties are
given below:
[ Category ( User Defined ) , Description
( Controls the Alarm Time ) ]
public DateTime AlarmTime
{
get
{
return altime ;
}
set
{
altime = value ;
}
}
[ Category ( User Defined ), Description
( Controls
the Alarm Message ) ]
public string message
{
get
{
return almessage ;
}
set
{
almessage = value ;
}
}
Notice the two attributes that we applied to the properties.
The Category attribute specifies the category under which the property gets
displayed in the Properties window. This would be visible whenever we drag the
control on the form and open the Properties window. The Description attribute
accepts a String that gets displayed in a small part of the window present at
the end of the Properties window. This string describes the property. The Properties
window of the control is shown in the following figure.
To add the event we have first added a delegate called
NotifyAlarm to the control that accepts two parametersan object and a
TimeEventArgs object.
public delegate void NotifyAlarm ( object sender, TimeEventArgs
e ) ;
TimeEventArgs is a user-defined class. In this class we have added a data member
named msg of type String and a one-argument constructor accepting a string that
is stored in msg. The class is shown below:
public class TimeEventArgs : EventArgs
{
public string msg ;
public TimeEventArgs ( string s )
{
msg = s ;
}
}
Next we added the event as a data member of the class as
shown below:
public event NotifyAlarm alarm ;
For the alarm to ring at the specified time, with every minute we must check
whether the specified alarm time is equal to the time displayed in our control.
We have done the checking in the Tick event handler. The modified Tick event
handler is given below.
private void mytimer_Tick ( object sender, System.EventArgs
e )
{
g.TranslateTransform ( 60, 60 ) ;
for ( int i = 0 ; i <= 12 ; i++ )
{
g.FillRectangle ( b, -2, -45, 4, 5 ) ;
g.RotateTransform ( 30 ) ;
}
g.ResetTransform( ) ;
//seconds
p.Width = 1 ;
p.EndCap = LineCap.Flat ;
p.Color = Color.Red ;
g.TranslateTransform ( 60, 60 ) ;
g.RotateTransform ( s ) ;
g.DrawLine ( p, 0, 0, 0, -40 ) ;
g.ResetTransform( ) ;
//minutes
p.Width = 3 ;
p.EndCap = LineCap.Triangle ;
p.Color = Color.Blue ;
g.TranslateTransform ( 60, 60 ) ;
g.RotateTransform ( m ) ;
g.DrawLine ( p, 0, 0, 0, -30 ) ;
g.ResetTransform( ) ;
//hours
p.Width = 4 ;
g.TranslateTransform ( 60, 60 ) ;
g.RotateTransform ( h ) ;
g.DrawLine ( p, 0, 0, 0, -20 ) ;
g.ResetTransform( ) ;
s += 6 ;
if (s == 360 )
s = 0 ;
sec = sec + 1 ;
if (sec == 60)
{
sec = 0 ;
m += 6 ;
if (m == 360)
m = 0 ;
min = min + 1 ;
if ( altime.Hour == hr
&& altime.Minute == min )
{
TimeEventArgs t = new TimeEventArgs
( almessage ) ;
alarm ( this, t ) ;
}
h += 0.5f ;
if ( h == 360 )
h = 0 ;
if ( min == 60 )
{
min = 0 ;
hr += 1 ;
}
}
Size sz = this.Size ;
Rectangle rect = new Rectangle ( 0, 0, sz.Width,
sz.Height ) ;
Bitmap bm = mybmp.Clone ( rect,
mybmp.PixelFormat ) ;
this.BackgroundImage = bm ;
Color bkclr = this.BackColor ;
g.Clear ( bkclr ) ;
}
As soon as altime.Hour becomes equal to hr and altime.Minute
becomes equal to min, we created an object referred to by t of the TimeEventArgs
class by passing almessage to it. Next we raised the event using RaiseEvent
and passed the reference of the control to it.
We have also added an attribute called DefaultEvent
to the Clock class as shown below:
[ DefaultProperty ( Message ) , DefaultEvent
( alarm ) ]
As a result, whenever we drag our control on the form
and double-click on the control in the Clients Windows Designer, of all
the event handlers available, the alarm event handler would get added in the
code.
Now let us see what we need to do to handle the event
in the client. As soon as we double-click on the control after dragging it on
the form, the myclock_alarm( ) event handler gets added to the form class. To
display the alarm message we have simply popped a message box displaying the
alarm message. The handler is shown below.
private void myclock_alarm ( object sender, ClockCtrl.TimeEventArgs
e )
{
MessageBox.Show ( e.msg ) ;
}
In the client, on selecting AlarmTime in the Properties window,
we get a calendar control. We have set the values for AlarmTime and Message
properties. When the clock reaches the alarm time it displays the message as
shown alongside.
 |
Yashavant Kanetkar, one of the first Express Computer
columnists, is an established software expert, speaker and author with several
best-sellers to his credit, including titles like “Let Us C” and the “Fundas”
series. Contact him at kanet@nagpur.dot.net.in |
|