LordAro
LordAro

Reputation: 1289

Set up single event handler for multiple forms

I have some forms, and in them i have some event functions which are basically identical

I have tried to implement a 'Shared' class and link the Eventhandler to that function, but when i give the function the necessary protection level, it complains about it's non-static-ness and i have to make it static also.

I'm not a fan of static functions, and so ask: Is there a better way to do it?

(In case the above is unclear: I want to do this: Set up single event handler for multiple buttons in .NET? but with multiple forms instead of multiple controls)

EDIT: as per request for more info:

I'm fairly OCD about code duplication, and my program has multiple forms active/hidden at the same time, and obviously i want to close the whole program when the 'x' is pressed so:

class Shared
{
    public static void FormClosed(object sender, FormClosedEventArgs e)
    {
        Application.Exit();
    }

    public static void FormClosing(object sender, FormClosingEventArgs e)
    {
        if (MessageBox.Show("Are you sure you want to exit?", "Confirm exit", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) {
            e.Cancel = true;
        }
    }
}

Very simple functions, i know, but i don't like duplication :P

The above 'configuration' of 'public static' works fine, but i just wondered if there was a 'better way' (tm)

Upvotes: 0

Views: 3187

Answers (2)

IAbstract
IAbstract

Reputation: 19881

If you don't want a static class, you have 2 easy options to suit most preferences:

  • singleton
  • pass parameter to form ctor

For a singleton:

class EventMangler {

   private static readonly _instance = new SomeHandler ();

   // although you don't like static methods  :(
   static EventMangler Instance {
      get { return _instance; }

   public void SomeEventHandler (object sender, EventArgs e) {
      // handle event
   }
}

// use EventMangler.Instance
public MyForm () {
   InitializeComponent();
   button1.Click += EventMangler.Instance.SomeEventHandler;
}

To pass a parameter to the Form's constructor, you have more choices: (a) pass reference to the handler's object, or (b) pass a reference to the handler itself. I prefer option (b) for a single handler. Otherwise, if the parent object - e.g. EventMangler - has multiple handlers, use option (a):

// remove singleton Instance method from EventMangler
// instantiate EventMangler in Program and pass to Form ctors

// pass a single handler reference as Action
public MyForm (Action<object, EventArgs> handler) {
   InitializeComponent();
   button1.Click += handler;
}

Upvotes: 1

Ilya Ivanov
Ilya Ivanov

Reputation: 23626

You can use static method and then delegate handling to instance and only then use all prettiness of OOP

public static void GeneralHandler(object sender, EventArgs args)
{
    instance.Handle(sender, args);
}
private static MyProcessingClass instance = new MyProcessingClass();

Subscribe like

button1.Event1 += GeneralHandler;
Button1.Event2 += GeneralHandler;
Button1.Event1 += GeneralHandler;

You can further enhance your implementation to support Dependency Injection, like introduce HandlerProvider and encapsulate creating mechanism there, while exposing only interface outside

Upvotes: 1

Related Questions