Previous Page
Next Page

Using Delegates

In the following exercise, you will create a delegate to encapsulate a method that displays the time in a Microsoft Windows text box. You will attach the delegate object to a class called Ticker that invokes the delegate every second. In this way, you will create a Windows application that acts as a simple digital clock.

Finish the digital clock application
  1. Start Microsoft Visual Studio 2005.

  2. Open the Delegates project, located in the \Microsoft Press\Visual CSharp Step by Step\Chapter 16\Delegates folder in your My Documents folder.

  3. On the Debug menu, click Start Without Debugging.

    The project builds and runs. A Windows form displays a digital clock. The clock displays the wrong time.

  4. Click Start, and then click Stop.

    Nothing happens. The Start and Stop methods have not been implemented yet. Your task is to implement these methods.

  5. Close the window to return to the Visual Studio 2005 environment.

  6. Open the Ticker.cs source file and display it in the Code and Text Editor window. This file contains a class called Ticker, that models the inner workings of a clock. It uses a System.Timers.Timer object, called ticking, to arrange for a pulse to be sent every second. This class catches the pulse by using an event (events will be described shortly), and then arranges for the display to be updated by invoking a delegate.

  7. In the Code and Text Editor window, locate the declaration of the Tick delegate. It is located near the top of the file and looks like this:

    public delegate void Tick(int hh, int mm, int ss);

    The Tick delegate can be used to refer to a method that takes three integer parameters, but does not return a value. There is a delegate variable called tickers at the end of the class that is based on this type. The Add and Remove methods in this class allow matching methods to add and remove themselves from the tickers delegate variable:

    class Ticker
    {
        ... 
        public void Add(Tick newMethod)
        {
            this.tickers += newMethod; 
        }
    
        public void Remove(Tick oldMethod)
        {
            this.tickers -= oldMethod;
        }
        ...
        private Tick tickers;
    }
  8. Open the Clock.cs source file and display it in the Code and Text Editor window. The Clock class models the clock display. It has methods called Start and Stop which will be used to start and stop the clock running (when they are implemented), and a method called RefreshTime that formats a string to depict the time specified by its three parameters (hours, minutes, and seconds), and then displays it in the TextBox field called display. This TextBox field is initialized in the constructor. The class also contains a private Ticker field called pulsed, which tells the clock when to update its display:

    class Clock
    {
        ...
    
        public Clock(TextBox displayBox)
        {
            this.display = displayBox;
        }
        ...
        private void RefreshTime(int hh, int mm, int ss )
        {
            this.display.Text = string.Format("{0:D2}:{1:D2}:{2:D2}", hh, mm, ss); 
        }
    
        private Ticker pulsed = new Ticker();
        private TextBox display;
    }
  9. Display the code for the Form1.cs source file in the Code and Text Editor window. Notice that the constructor creates a new instance of the Clock class passing in the TextBox field called digital as its parameter:

    public Form1()
    {
        ...
        clock = new Clock(digital);
    }

    The digital field is the TextBox control displayed on the form. The clock will display its output in this TextBox.

  10. Return to the Clock.cs source file. Implement the Clock.Start method so that it adds the Clock.RefreshTime method to the delegate in the pulsed object by using the Ticker.Add method.

    The Start method should look like this:

    public void Start()
    {
        pulsed.Add(this.RefreshTime);
    }
  11. Implement the Clock.Stop method so that it removes the Clock.RefreshTime method from the delegate in the pulsed object by using the Ticker.Remove method.

    The Stop method should look like this:

    public void Stop()
    {
        pulsed.Remove(this.RefreshTime);
    }
  12. On the Debug menu, click Start Without Debugging. The project builds and runs.

  13. Click the Start button.

    The Windows form now displays the correct time and updates every second.

  14. Click Stop.

    The display stops responding or “freezes.” This is because the Stop button calls the Clock.Stop method, which removes the RefreshTime method from the Ticker delegate; RefreshTime is no longer being called every second.

  15. Click Start.

    The display resumes processing and updates the time every second. This is because the Start button calls the Clock.Start method, which attaches the RefreshTime method to the Ticker delegate again.

  16. Close the form.


Previous Page
Next Page