|
We can also add properties and events to a custom control. In last two articles we saw how to create and use a clock control. In this article we would 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
properties—AlarmTime 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 members-altime (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 would get 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 would get 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 parameters-an 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 would be 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 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 Client's 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 messagebox 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 would get a calendar control. We have set the values for
AlarmTime and Message properties. When the clock would reach the alarm time it would display the message as shown in the following figure.
|