SDanks
SDanks

Reputation: 671

Delegates and Events with multiple classes

This has taken me quite a few days to develop a demo of communicating between classes with delegates and events. I would like to know if this is the best practices way of accomplishing this passing of data between classes or not. If there is a better method please let me know. Specifically, if something happens in a subclass how do you get it back to the main class. This would be particularly useful when doing n-tier architecture by separating out the User Interface from the Business Logic Level, and the Data Access Level.

I have a form that has 3 text boxes: tb1, tb2, and tbAnswer. I also have a button that says "Add" and it is just button1.

The main form is:

namespace DelegateTest
{
    public delegate void ShowMessage(object sender, Form1.AnswerEventArgs e);

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void a_OnShowMessage(object sender, AnswerEventArgs e)
        {
            tbAnswer.Text = e.answer;
        }

        public class AnswerEventArgs :EventArgs
        {
            public string answer { get; set; }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            AddClass a = new AddClass();
            a.OnShowMessage += new ShowMessage(a_OnShowMessage);
            a.AddMe(Convert.ToInt16(tb1.Text), Convert.ToInt16(tb2.Text));
        }
    }
}

and the subform called AddClass.cs is:

namespace DelegateTest
{
    class AddClass
    {
        public event ShowMessage OnShowMessage;
        public void AddMe(int a, int b)
        {
            Form1.AnswerEventArgs e = new Form1.AnswerEventArgs();
            e.answer = (a+b).ToString();
            OnShowMessage(this, e);
        }
    }
}

Upvotes: 1

Views: 2671

Answers (1)

piedar
piedar

Reputation: 2711

Your approach is sound except for two details.

First, a NullPointerException will occur if your event is raised before any handlers are added. You can get around this in one of two ways.

1) Make a local copy (to avoid race condition) and check it for null:

var showMessage = OnShowMessage;
if (showMessage != null)
{
    showMessage(this, e);
}

2) Initialize your event to an empty delegate:

public event ShowMessage OnShowMessage = delegate { };

Second, you do not need to declare your own delegate in this case. You can simply create a standard EventHandler with your own event args:

public event EventHandler<Form1.AnswerEventArgs> OnShowMessage = delegate { };

See How to: Publish Events that Conform to .NET Framework Guidelines for more information.

Upvotes: 2

Related Questions