Reputation: 671
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
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