Programming with Events in CS

Simple Sample

Events were extremely simple in VB 6. You raised and event in your class, and the called it using WithEvents on your form. It is not that simple in CS.

To create an event in CS, three steps must be taken in the class that raises the event:

1. Create a delegate that references the event. In this case StatusChangeEvent

2. Create an instance of the delegate. In this case EventStatus

3. Create a function that wraps the instace so that you do not write stauts, in our case, to a null pointer.

Here is the code for class

using System;
using System.Threading;

namespace CS_SimpleEvents
{
    //simple structure for communicating between the form (calling object)
    // and a class
    public class StatusArgs
    {
        public string Status;
        public int Position;
        public int MaxPosition;
        public bool Continue = true;

        public int PercentComplete
        {
            get { return MaxPosition>0 ? Position * 100 / MaxPosition:0; }
        }

    }

    public class Counter : IDisposable
    {
        /*Status change event pointers */
        public delegate void StatusChangeEvent(StatusArgs sa);
        public StatusChangeEvent StatusChange = null;

        //use in place of a destructor for cleanup;
        public void Dispose()
        {

        }
        public void Count(int nMax, int nSleep, string nThreadName)
        {
            StatusArgs sa = null;

            for (int x = 0; x < nMax; x++)
            {
                sa = new StatusArgs();
                sa.Status = nThreadName + " counting";
                sa.Position = x;
                sa.MaxPosition = nMax;

                StatusChange(sa);

                Thread.Sleep(nSleep);

                if (!sa.Continue)
                {
                    sa.Status = nThreadName = " terminated by client";
                    OnStatusChange(sa);
                    break;

                }
            }
        }
        public void OnStatusChange(StatusArgs sa)
        {
            //need to test delegates for null.
            //value would be null, if calling function
            //does not implement the event
            if (StatusChange != null)
            {
                StatusChange(sa);
            }
        }
    }
}

Form Code

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace CS_SimpleEvents
{


    public partial class frmMain : Form
    {
        bool _bCont = false;


        public frmMain()
        {
            InitializeComponent();

            pbStatus.Maximum = 100;
            pbStatus.Minimum = 0;
        }

        private void btnCount_Click(object sender, EventArgs e)
        {
            _bCont = ! _bCont;

            rtbStatus.Clear();

            if (_bCont)
            {
                btnCount.Text = "stop";

                Counter cnt = new Counter();
                cnt.StatusChange += new Counter.StatusChangeEvent(onStatusUpdate);

                cnt.Count(25, 10, "single thread");
                cnt.Dispose();
                cnt.StatusChange -= new Counter.StatusChangeEvent(onStatusUpdate);

            }
            _bCont = false;
            btnCount.Text = "start";

        }
        private void onStatusUpdate(StatusArgs sa)
        {
            if (sa.PercentComplete <= 100)
            {
                pbStatus.Value = sa.PercentComplete;
            }
            rtbStatus.AppendText(sa.Status + "\r\n");
            sa.Continue = _bCont;

            Application.DoEvents();
        }
    }
}

To download all of the files to run this program inVS 2008, click "CS_WithEvents.zip"

To e-mail a suggestion or comment click on: sam@gilcrist.com

Return to www.gilcrist.com