Posted by: Cirilo Meggiolaro | 12/16/2008

Tip of the day #63 – Custom events with custom arguments classes

Let’s check today how to create custom events classes with custom event arguments.

For this tip we are going to create an event for a simple stock management class that is raised when a product is requested from the stock but there are not enough products available. It is just an example scenario and it does not reflect a real stock application.

Event arguments class

To create a custom event arguments class you must define a class that inherits from the base System.EventArgs class and create as much properties as your code needs.

Let’s create an event argument class named StockEventArgs and two read-only properties that are going to store a custom message and the number of products remaining in stock. The following code is the final event argument class:

public class StockEventArgs : EventArgs
{
    private string _message = string.Empty;
    private int _itemsRemaining = 0;

    public StockEventArgs(string message, int itemsRemaining)
    {
        _message = message;
        _itemsRemaining = itemsRemaining;
    }

    public string Message
    {
        get
        {
            return _message;
        }
    }

    public int ItemsRemaining
    {
        get
        {
            return _itemsRemaining;
        }
    }
}

Event Handler

A delegate that defines the event handler method with our custom event arguments must be added on the application level;

public delegate void StockEventHandler(object sender, StockEventArgs e);

Stock Class

The stock class will have the following methods and objects:

  • An event object from the StockEventHandler type named StockUnavailable. This is the name that you’ll see when registering the event handler on your client application;

public event StockEventHandler StockUnavailable;

  • Class constructor: The class constructor sets a random quantity for the current stock in a local field;

public Stock();

  • A method to remove items from the stock: This method will check whether there are products in stock or not. If there are not enough products the OnStockUnavailable method will be invoked and the event raised;

public void RemoveItem(int quantity);

  • OnStockUnavailable method: The idea of this method is to have a centralized operation that invokes the event. By defining the scope as protected derived classes will be able to invoke and declaring the method as virtual makes the method overridable by the child classes;

protected virtual void OnStockUnavailable();

  • A local variable that stores the current stock number:

private int totalInStock;

  • The following code snippet is the final stock class:

public class Stock
{
    public event StockEventHandler StockUnavailable;
    private int totalInStock = 0;

    public Stock()
    {
        /// Defines a random stock
        totalInStock = 50;
    }

    public void RemoveItem(int quantity)
    {
        if (totalInStock < quantity)
        {
            OnStockUnavailable();
        }
        else
        {
            totalInStock -= quantity;
        }
    }

    protected virtual void OnStockUnavailable()
    {
        if (StockUnavailable != null)
        {
            StockEventArgs e = new StockEventArgs(“There are not enough products in stock.”, totalInStock);
            StockUnavailable(this, e);
        }
    }
}

Consuming the class and adding the event handler

To be notified when a product goes out of stock you need to follow the steps:

  • Create a Stock class instance;
  • Add the StockUnavailable event handler;
  • Create the method that will handle the event. For our example we are going to use a MessageBox to display the custom properties available in the event arguments parameter;
  • Remove products until the product goes out of scope;
  • I created a simple Windows form application that removes items from the stock like the following screenshot:
Picture 1 - The custom event example

Picture 1 - The custom event example

Let’s check the final code;

public partial class frmStock : Form
{
    Stock productStock = null;

    public frmStock()
    {
        InitializeComponent();
    }

    private void btnRemove_Click(object sender, EventArgs e)
    {
        productStock.RemoveItem(Convert.ToInt32(numStock.Value));
        numStock.Value = 0;
    }

    private void frmStock_Load(object sender, EventArgs e)
    {
        productStock = new Stock();
        productStock.StockUnavailable += new StockEventHandler(productStock_StockUnavailable);
    }

    private void productStock_StockUnavailable(object sender, StockEventArgs e)
    {
        MessageBox.Show(e.Message);
        MessageBox.Show(“Items remaining: “ + e.ItemsRemaining.ToString());
    }
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: