Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling C# events from outside the owning class?

Is it possible under any set of circumstances to be able to accomplish this?

My current circumstances are this:

public class CustomForm : Form
{
    public class CustomGUIElement
    {
    ...
        public event MouseEventHandler Click;
        // etc, and so forth.
    ...
    }

    private List<CustomGUIElement> _elements;

    ...

    public void CustomForm_Click(object sender, MouseEventArgs e)
    {
        // we might want to call one of the _elements[n].Click in here
        // but we can't because we aren't in the same class.
    }
}

My first thought was to have a function similar to:

internal enum GUIElementHandlers { Click, ... }
internal void CustomGUIElement::CallHandler(GUIElementHandler h, object[] args) {
    switch (h) {
        case Click:
            this.Click(this, (EventArgs)args[0]);
            break;
        ... // etc and so forth
    }
}

It's a horribly ugly kludge, but it should work... There must be a more elegant solution though? The .NET library does this all the time with message handlers and calling events in Control's. Does anyone else have any other/better ideas?

like image 976
Matthew Scharley Avatar asked Sep 20 '08 11:09

Matthew Scharley


People also ask

What is calling function in C?

When a program calls a function, the program control is transferred to the called function. A called function performs a defined task and when its return statement is executed or when its function-ending closing brace is reached, it returns the program control back to the main program.

Can you call C from C++?

Just declare the C function extern "C" (in your C++ code) and call it (from your C or C++ code). For example: // C++ code.

What is call by value in C?

The call by value method of passing arguments to a function copies the actual value of an argument into the formal parameter of the function. In this case, changes made to the parameter inside the function have no effect on the argument. By default, C programming uses call by value to pass arguments.


2 Answers

You just need to add a public method for invoking the event. Microsoft already does this for some events such as PerformClick for controls that expose a Click event.

public class CustomGUIElement    
{
    public void PerformClick()
    {
        OnClick(EventArgs.Empty);
    }

    protected virtual void OnClick(EventArgs e)
    {
        if (Click != null)
            Click(this, e);
    }
}

You would then do the following inside your example event handler...

public void CustomForm_Click(object sender, MouseEventArgs e)        
{
    _elements[0].PerformClick();
}
like image 173
Phil Wright Avatar answered Oct 04 '22 15:10

Phil Wright


The event keyword in c# modifies the declaration of the delegate. It prevents direct assignment to the delegate (you can only use += and -= on an event), and it prevents invocation of the delegate from outside the class.

So you could alter your code to look like this:

public class CustomGUIElement
{
...
    public MouseEventHandler Click;
    // etc, and so forth.
...
}

Then you can invoke the event from outside the class like this.

myCustomGUIElement.Click(sender,args);

The drawback is that code using the class can overwrite any registered handlers very easily with code like this:

myCustomGUIElement.Click = null;

which is not allowed if the Click delegate is declared as an event.

like image 42
Lee Avatar answered Oct 04 '22 16:10

Lee