How to Pass an Event to a Method

Pass an event as a parameter to a method

You have in fact discovered that events are not "first class" in C#; you cannot pass around an event as data. You can pass around a delegate to a method associated with a receiver as a first-class object by making a delegate. You can pass around a reference to any variable as a (mostly) first-class object. (I say "mostly" because references to variables cannot be stored in fields, stored in arrays, and so on; they are highly restricted compared to other kinds of data.) You can pass around a type by obtaining its Type object and passing that around.

But there is no way to directly pass around as data an event, property, indexer, constructor or destructor associated with a particular instance. The best you can do is to make a delegate (or pair of delegates) out of a lambda, as you suggest. Or, obtain the reflection object associated with the event and pass that around, along with the instance.

How to pass an event to a method?

My original answer was suitable from within the class that defined the event, but you've since updated your question to reflect that you wish to accomplish this from outside the defining class, so I've stricken that.

Only the class that defines an event can refer to the implicit delegate variable that the event uses. From outside that class, you only have access to the add and remove methods, via += and -=. This means that you can't do what you're asking, directly. You can, however, use a functional approach.

class A{
public event EventHandler Event1;

public void TriggerEvent1(){
if(Event1 != null)
Event1(this, EventArgs.Empty);
}
}

class B{
static void HandleEvent(object o, EventArgs e){
Console.WriteLine("Woo-hoo!");
}

static void AttachToEvent(Action<EventHandler> attach){
attach(HandleEvent);
}

static void Main(){
A a = new A();
AttachToEvent(handler=>a.Event1 += handler);
a.TriggerEvent1();
}
}

How to pass an event object to a function in Javascript?

Although this is the accepted answer, toto_tico's answer below is better :)

Try making the onclick js use 'return' to ensure the desired return value gets used...

<button type="button" value="click me" onclick="return check_me();" />

How to pass event into method in a JavaScript class?

  • The first task was to make the code run.
  • The second task is going to provide detailed explanation of what actually happens and why one does not need at all an approach that runs with a JavaScript class.

class ListItems{  constructor(listItemQuery) {    const listItems = this;
listItemQuery.forEach((listItem) => { listItem.addEventListener('click', listItems.clickGreen, false); listItem.addEventListener('onmousedown', listItems.noSelectText, false); }); } noSelectText(evt) { evt.preventDefault; return false; }
clickGreen(evt) { const listItem = evt.currentTarget;
if (evt.ctrlKey || evt.metaKey) { listItem.classList.add('selected'); return; } const firstLevelListItems = Array.from(listItem.parentNode.children);
firstLevelListItems.forEach(function(item) { item.classList.remove('selected'); }); listItem.classList.add('selected'); }}
function initializeListItems() { new ListItems(document.querySelectorAll('li'));}window.addEventListener('load', initializeListItems, false);
.as-console-wrapper { max-height: 100%!important; top: 0; }
<!doctype html><html>  <head>    <meta charset="utf-8">    <style>      .selected {        background: #0f0;      }      li {        cursor: pointer;      }    </style>  </head>  <body>    Кликни на элемент списка, чтобы выделить его.    <br/>    <ul id="ul">      <li>Кристофер Робин</li>      <li>Винни Пух</li>      <li>Тигра</li>      <li>Кенга</li>      <li>Кролик. Просто Кролик.</li>    </ul>  </body></html>

How to pass event as argument to an inline event handler in JavaScript?

to pass the event object:

<p id="p" onclick="doSomething(event)">

to get the clicked child element (should be used with event parameter:

function doSomething(e) {
e = e || window.event;
var target = e.target || e.srcElement;
console.log(target);
}

to pass the element itself (DOMElement):

<p id="p" onclick="doThing(this)">

see live example on jsFiddle.

You can specify the name of the event as above, but alternatively your handler can access the event parameter as described here: "When the event handler is specified as an HTML attribute, the specified code is wrapped into a function with the following parameters". There's much more additional documentation at the link.

How to pass an event to a method and then subscribe to it?

You are mixing events with delegates. You should probably read this article by Jon Skeet which will explain the differences between the two.

The reason the second option doesn't work is because the method expects a parameter that is a delegate that conforms to the EventHandler signature.Button.Click refers to an event rather than a delegate. Events just encapsulate delegates.

I'm not sure what you are trying can be done. Conceptually what you want to do doesn't actually make sense; it is the logic of the handler you want to pass around not the event itself.

Take a look at this post which looks at some ways of simulating the effect you want.

How to pass event from component to nested function?

You'll need to proxy the event object through on all click handlers. I like to use curried functions to make attaching the click handler a little simpler. Don't forget to add a react key to the mapped icons.

export const useCategories = () => {
const handleClick = (event, category, something) => {
event.stopPropagation();
console.log(category, something);
};

return {
icon: {
// curried function to receive category and return onClick handler
onClick: category => event => handleClick(event, category, 'anything'),
}
}
}

export const Categories = () => {
const { icon } = useCategories();

return (
<div>
{categories.map((category, index) => (
<Icon
key={index}
onClick={icon.onClick(category)} // <-- set category
/>
)
</div>
);
}

How can I pass an event to a function in C#?

The reason why this does not work is += when applied to a delegate creates a new delegate which is the combination of the old and the new. It does not modify the existing delegate.

In order to get this to work you will have to pass the delegate by reference.

public static void Helper(ref EventHandler<EventArgs> e)
{
e+= (x,y) => {};
}

The reason this works outside of the method is because the LHS is still the actual field. So += will create a new delegate and assign back to the member field.

How can I pass the DOM event as an event handler bind method

You can pass arguments:

const handleHover = (event, opacity) => { 
event.target.style.opacity = opacity;
}

nav.addEventListener('mouseover', () => handleHover(event, 0.5));
<div id="nav">Mouse Over</div>

Passing a event as an argument into a method

You don't - an event is like a property, it's just syntactic sugar around a pair of methods (add/remove instead of the get/set for a property). F# actually does expose events as first class citizens, but C# doesn't :(

There are a few options though:

  • Pass in an "event subscriber" delegate that you call with the new handler you want to add (and potentially an event unsubscriber delegate too). Something like this:

    new Receiver(handler => button.Click += handler, ...)
  • Pass in an EventInfo and subscribe with reflection (urgh)

  • Look into the Reactive Extensions framework, which has various ways of working with events (using reflection, but it means Microsoft does the reflection work rather than you :)

We could give better advice if we knew the bigger picture - care to inform us more?

EDIT: Okay, so in this case you'd need to pass in both the subscription and unsubscription code:

using (new EventGuard<EventArgs>(h => Proxy.RetrieveCompleted += h, 
h => Proxy.RetrieveCompleted -= h,
HandleRetrieveCompleted))
{
...
}

That's pretty nasty, admittedly. You may well find there's something nicer in Reactive Extensions, but that would at least work...



Related Topics



Leave a reply



Submit