I've been spending some time learning about Delegates in C# and have wired up a small Windows Form app containing two forms to test them out.
My goal is to have the AddContactForm push new Contact data back to the ContactsForm using an EventHandler delegate. I currently have this working with the code below, however ultimately I'd like to make ContactAddedHandler in the AddContactForm private, and pass in a function to the AddContactForm constructor, which is used to subscribe to the delegate like so:
public AddContactForm(SomeSubscriberFunction foo)
{
ContactAddedHandler += foo;
}
I've tried making SomeSubscriberFunction various permutations of the following without success:
Func<object?, AddContactEventArgs?>Func<AddContactEventArgs?>Action<object?, AddContactEventArgs?>
If anyone could provide any guidance on the following two questions, it would be greatly appreciated:
#1. Am I approaching this problem in a completely non-best practice way, if so what is the correct approach.
#2. If this approach using delegates is correct, how can I achieve what I am attempting to do?
Thank you.
ContactsForm
public void addContactBtn_Click(Object sender, EventArgs e)
{
AddContactForm addContactForm = new AddContactForm();
addContactForm.ContactAddedHandler += ContactAdded;
addContactForm.Show();
}
public void ContactAdded(object? sender, AddContactForm.AddContactEventArgs e)
{
Console.Write("Contact Added");
}
AddContactForm
public partial class AddContactForm : Form
{
public class AddContactEventArgs(Contact contact) : EventArgs
{
public Contact contact = contact;
}
public event EventHandler<AddContactEventArgs>? ContactAddedHandler;
public AddContactForm()
{
InitializeComponent();
}
private void saveContactBtn_Click(object sender, EventArgs e)
{
Contact c = new Contact("Test");
AddContactEventArgs args = new AddContactEventArgs(c);
if (ContactAddedHandler != null)
{
ContactAddedHandler(this, args);
}
}
}

Action delegates are quite often used to generate notifications in similar scenarios. You already have a
Contactclass object, that's the object that stores the required information, so you most probably don't need a custom EventArgs object to wrap the same data.For example, if the Action delegate notification is restricted to only the code that creates the Form class:
Note: written for .NET 6+, since you had the
windows-forms-coretagIf the Action delegate can only be injected via the Form's Constructor, as shown in this post, you can simply assign the delegate to a private Field and invoke it when needed:
You could also make the Action accessible from the outside and add more than one subscriber.
You can use a multicast delegate as it was used before. But better create a level of indirection, adding the
eventkeyword, soadd()andremove()methods are created under the hood, to protect the object.You can do this, in the Constructor of
AddContactForm:but not this, somewhere else:
You can then add multiple delegates, where the instance of
AddContactFormis visible, to anything else that can pass an Action delegate or in many different other ways: