Quantcast
Viewing all articles
Browse latest Browse all 25

DataEventArgs: a generic EventArgs Class

Back in the bad old days, before generics, writing custom event handlers to pass additional data to the event subscriber was a pain in the butt. With the built in .NET 1.0 EventHandler you can signal that an event occured. Thats' fine except that the event handler usually needs more information about an event in order to do its job. Under .NET 1.0 you have a couple of solutions. You can cast the sender object to a specific known type and pull off the properties you need or you could define a delegate for the EventHandler and also subclass the EventArgs class to define the additional data to be passed to the handler. Casting the sender leads to brittle, highly coupled code. Creating the delegate and EventArgs subclass is not overly difficult but it does eat some brain cycles and leads to an explosion of classes.

Fortunately, with CAB and .NET 2.0 generics there is a much easier way called DataEventArgs. No casting, no delegate and no EventArgs subclass needed. Here's how you use it. First, define your event along with the custom data that will be send to the handler like this:

publiceventEventHandler<DataEventArgs<Account>> AccountSelected;

In this example I am defining an event called AccountSelected and the event publisher will pass an Account object to the event subscriber. Account is just one of my domain model classes but it could be any type of object including something like a string or int.

Whenever a new Account is selected I can raise the AccountSelected event with this code:

publicvoid OnAccountSelected(Account a)
{
   if (AccountSelected != null)
   {
      AccountSelected(
this, newDataEventArgs<Account>(a));
   }
}

publicvoid OnAccountSelected(Account a)
{
   if (AccountSelected != null)
   {
      AccountSelected(
this, newDataEventArgs<Account>(a));
   }
}

Now your subscriber (the event handler) simply reads the data off the passed DataEventArgs object.

publicvoid AccountSelected(object sender, DataEventArgs<Account> e)
{
  
ShowView();
   presenter.SelectAccount(e.Data);
}

publicvoid AccountSelected(object sender, DataEventArgs<Account> e)
{
  
ShowView();
   presenter.SelectAccount(e.Data);
}

This is much simpler than the equivalent 1.0 code. The passed data is exposed in the Data property of the EventArgs object and it doesn't need to be casted to use it.

If you want to use this class just include it in your own library.

//===============================================================================
// Microsoft patterns & practices
// CompositeUI Application Block
//===============================================================================
// Copyright © Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================

using System;
using System.Collections.Generic;
using System.Text;

namespace Microsoft.Practices.CompositeUI.Utility
{
    public class DataEventArgs<TData> : EventArgs
    {
        TData data;

        public DataEventArgs(TData data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            this.data = data;
        }

        public TData Data
        {
            get { return data; }
        }

        public override string ToString()
        {
            return data.ToString();
        }
    }
}

//===============================================================================
// Microsoft patterns & practices
// CompositeUI Application Block
//===============================================================================
// Copyright © Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================

using System;
using System.Collections.Generic;
using System.Text;

namespace Microsoft.Practices.CompositeUI.Utility
{
    public class DataEventArgs<TData> : EventArgs
    {
        TData data;

        public DataEventArgs(TData data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            this.data = data;
        }

        public TData Data
        {
            get { return data; }
        }

        public override string ToString()
        {
            return data.ToString();
        }
    }
}
Image may be NSFW.
Clik here to view.

Viewing all articles
Browse latest Browse all 25

Trending Articles