(Beginner's question, if offended please move on, otherwise your input is welcome)
Im trying to invoke datagridview events in Wpf code. Implementing the event calling is straight forward.
for example:
dgv1.ColumnHeaderMouseClick+=delegate(
object sender, DataGridViewCellMouseEventArgs e)
{..code on event..};
My question: what is the propper way to invoke the dgv event somewhere else in the code. (press the header column programmatically).
Thank you
A cleaner way for me is to separate the method of of your custom event.
Something like this:
private void DataGrid_Sorting(object sender, DataGridSortingEventArgs e)
{
MessageBox.Show("Sorting was executed.");
}
Then set that method to the event property of the control like this:
dataGrid.Sorting += DataGrid_Sorting;
With this code won't get messy and readability is still intact.
I hope it helps you. Happy coding.
I think the only "supported" way (that is, not doing something with Windows messages and generally ignoring the .NET framework) would be to call OnColumnHeaderMouseClick. Which is what the method is for, except it's protected because it's really for someone doing their own version of the control, not for any random person to start firing off events.
So you could either subclass DataGridView and add a public method to wrap OnColumnHeaderMouseClick or you could use reflection to call the method even though it's not public.
This is a common pattern in C#. When you write
public event EventHandler XxxEvent;
it turns into something like
private EventHandler _XxxEvent;
public event EventHandler XxxEvent
{
add { _XxxEvent += value; }
remove { _XxxEvent -= value; }
}
(plus some handling of null, don't actually use that code as-is).
XxxEvent is not actually a delegate that can be invoked outside the class (you'll get a compiler error "The event 'ClassName.XxxEvent' can only appear on the left hand side of += or -="). And the _XxxEvent backing field is not something you're actually supposed to know about and is private anyway. So if you want anyone to be able to inherit from your class you conventionally have a method whose name is the same as the event prefixed with "On"
protected void OnXxxEvent(EventArgs args)
{
XxxEvent?.Invoke(this, args);
}
If I subscribe a new Method to a Handler and Press "Tab" twice after the "+=" VS will implement a Body like:
public class A {
public A(){
button1.Click += OnButton1Click();
}
private OnButton1Click(object sender, EventArgs e){
}
}
How can I change VS to create the Body of the Method as public instead of private?
Kind regards,
Asat0r
How can I change VS to create the Body of the Method as public instead
of private?
Not sure if there is any option but why you would like to do that? event handlers are not meant to be public. If you want to call the logic inside handler from some other type then refactor that logic to a helper method and re-use that instead probably.
Other answers have suggested that the method shouldn't be public.
Broadly speaking, I reject that - at least without further justification. If you want to expose a method with exactly that signature, I'd normally go ahead and do so. Two caveats around that though:
Normally the signature of an event handler isn't useful except as an event handler; the parameters aren't generally useful when calling the method directly. There are exceptions to that as ever.
If you subscribe an event handler with a public method, any other code can unsubscribe that event handler by creating an equal delegate. If you control all the code in the application, that's not much of a problem.
Both cases can be solved by exposing a public method with exactly the parameters you want (which could still be event handler parameters, but often won't be) and then using a lambda expression to subscribe to the event:
// I want to be able to call this from other code
public void SaveItem()
{
// ...
}
// Hook up the event handler using a lambda expression
saveButton.Click += (sender, args) => SaveItem();
On the other hand, if neither of the bullet points are an issue, go ahead and make the method public manually. I wouldn't expect there to be a VS shortcut to do so, but simply specifying the public modifier is pretty simple.
Is there anything in c# that you can use to create a collection of events like lists, hashsets, and a dictionary in this case? Thankyou.
Sure you can:
Dictionary<String, Delegate> m_events = new Dictionary<String, Delegate>();
In Jeff Richter's Book CLR via C# you can find a complete implementation of an EventSet class.
(Even if you don't have the book you can download the sample code from https://www.wintellect.com/wp-content/uploads/2017/09/CLR-via-C-4th-Edition-Code.zip. The class in question is in "Ch11-1-EventSet.cs".)
As far as the question goes what an event is:
Say you have this line of code in your class:
public event EventHandler<NewMailEventArgs> NewMail;
then the C# compiler will translate the line above into three constructs:
A private delegate field. (Something like: private EventHandler<NewMailEventArgs> NewMail;
A public add_Xxx method (where Xxx is the Event name) that interested subscribers can use to register a callback delegate with the event.
A public remove_Xxx method (where Xxx is the Event name) that subscribers can use to unregister from the event.
(All the gory details can be found in section 11.2 of aforementioned book.)
So in other words the 'thing' you can store in your Event collection class is just a plain old delegate nothing else.
An event is like a property or method; you cant store instances of them. You can use reflection, but this likely isn't what you want.
Did you mean you want to store a list of methods to call when your event is fired? Events already do that.
EDIT:
Ah, I think I get it now. If you just simply fire your event, only the B instances that want it will get it. If you pass into the event args the instance of A that fired the event, then the B instance will be able to tell where it came from. But a B will never get an event from an A that it didn't ask for an event.
EDIT:
Maybe not. You only want to fire an event on one of the B's? Make B implement an interface that has a callback method. Instead of firing an event, call the method on the correct instance of B.
You could use IList with out any trouble. Type T could be any type defined in .net or user defined class.
I have a ugly piece of code that adds event handlers. The problem is, if the code is called multiple times, the event handlers are called multiple times.
To solve the problem, I remove the event handler first and then add it.
Now I've seen the following behaviour:
Some event handlers can be checked like:
if (object.event == null) {
//
// Code
//
}
others of the form
if (object.object.event == null) {
//
// Code
//
}
I get a message like 'object.object.event' may only occur left of -= or +=.
(Since I'm using a german version of visual studio, I don't know the correct translation to english).
I have no idea why the behaviour looks this inconsequent so I would be grateful for some information on this.
To be more specific: It's user control.
if (myControl.Event == null) {
//
// works
//
}
if (myControl.TreeView.NodeMouseClick == null) {
//
// doesn't work
//
}
To solve the problem, I remove the event handler first and then add it.
That doesn't solve the problem. The event keyword provides accessors for a delegate object. Much like a property provides accessors for a field. On a property, you always need one get or set. An event has the add, remove and raise accessors. But the compiler will generate a default implementation for them if you don't do so yourself. Which is fairly common.
The advantage of a property accessor is that the backing field can be private. Nobody can mess with it, except the class that contains the field. All access has to go through the get and set accessors. The event keyword works exactly the same way, nobody can mess with the delegate object, except the code in the class that contains the event.
Which shoots a gaping hole in your attempt to avoid raising the event. You cannot mess with the list of subscribers for an event that's declared in another class, the compiler is telling you this. The normal way this is done is setting a bool flag to indicate that events have to be temporarily ignored. The event handler can check that flag and avoid executing any side-effects.
SLaks is correct, and has linked to some excellent resources. Here's a relevant quote from Chris Burrows' blog article:
Let me take a quick detour here and explain to you how the binding of += works in C#. There are two possibilities:
either there is an actual + operator, such as with ints, and x += y binds to “x = x + y” except that x is only evaluated once. This is the compound assignment operator; or
the thing on the left hand side is an event, and x.E += y binds to “x.add_E(y)”. This is the event accessor operator, and in fact this is the only way to bind to an event accessor.
So what do we have in the snippet above? Well, the extra bit of detail that you need to decide is the following rule about field-like events in C#: outside of the class or struct that defines a field-like event E, binding to the name E resolves to the event itself, on which the only legal operation is calling an accessor; inside the class or struct that defines a field-like event E, binding to the name E resolves to the private delegate field.
In your case, when resolving myControl.Event, you're inside the myControl class, so you don't see an event object; instead you see an actual delegate object, which you can compare with null. When resolving myControl.TreeView.NodeMouseClick, you're outside the TreeView class, so you can't access the actual delegate object; all you get is the event object, which cannot be compared to null.
If I understand correctly, all of this wouldn't help you anyway, since presumably after you check for null, you're going to try to fire the TreeView's event for it, which you can't do.
Depending on what you're trying to do, you could probably subclass TreeView and add an internal method that would call the protected TreeView.OnNodeMouseClick method to fire the event.
You can only access the backing field for an event defined in your class.
For more information, see the spec. (Although this has changed in C# 4, the changes are irrelevant to you)
Best practice in your case would be to create a protected internal OnEventName method in each class.
You can only query your own eventhandlers for attached listeners.
Automatic events, like this one:
public event EventHandler SomethingHappened;
are implemented by the compiler using a multicast delegate.
When you write myControl.Event == null, the compiler actually needs to call Delegate.GetInvocationList on that delegate. The compiler does not let you do that unless the code is inside a method of the class exposing the event, hence the error (it only allows you to add or remove from the invocation list).
If we were talking about an event you define in your own class, then you would have the option of exposing the invocation list (e.g. through a method) and doing what you are trying to do. But for existing classes (e.g. TreeView) it is not possible.
Is there any different between declaring event Action<> and event EventHandler<>.
Assuming it doesn't matter what object actually raised an event.
for example:
public event Action<bool, int, Blah> DiagnosticsEvent;
vs
public event EventHandler<DiagnosticsArgs> DiagnosticsEvent;
class DiagnosticsArgs : EventArgs
{
public DiagnosticsArgs(bool b, int i, Blah bl)
{...}
...
}
usage would be almost the same in both cases:
obj.DiagnosticsEvent += HandleDiagnosticsEvent;
There are several things that I don’t like about event EventHandler<> pattern:
Extra type declaration derived from
EventArgs
Compulsory passing of object source –
often no one cares
More code means more code to maintain without any clear advantage.
As a result, I prefer event Action<>
However, only if there are too many type arguments in Action<>, then an extra class would be required.
Based on some of the previous answers, I'm going to break my answer down into three areas.
First, physical limitations of using Action<T1, T2, T2... > vs using a derived class of EventArgs. There are three: First, if you change the number or types of parameters, every method that subscribes to will have to be changed to conform to the new pattern. If this is a public facing event that 3rd party assemblies will be using, and there is any possiblity that the event args would change, this would be a reason to use a custom class derived from event args for consistencies sake (remember, you COULD still use an Action<MyCustomClass>) Second, using Action<T1, T2, T2... > will prevent you from passing feedback BACK to the calling method unless you have a some kind of object (with a Handled property for instance) that is passed along with the Action. Third, you don't get named parameters, so if you're passing 3 bool's an int, two string's, and a DateTime, you have no idea what the meaning of those values are. As a side note, you can still have a "Fire this event safely method while still using Action<T1, T2, T2... >".
Secondly, consistency implications. If you have a large system you're already working with, it's nearly always better to follow the way the rest of the system is designed unless you have an very good reason not too. If you have publicly facing events that need to be maintained, the ability to substitute derived classes can be important. Keep that in mind.
Thirdly, real life practice, I personally find that I tend to create a lot of one off events for things like property changes that I need to interact with (Particularly when doing MVVM with view models that interact with each other) or where the event has a single parameter. Most of the time these events take on the form of public event Action<[classtype], bool> [PropertyName]Changed; or public event Action SomethingHappened;. In these cases, there are two benefits. First, I get a type for the issuing class. If MyClass declares and is the only class firing the event, I get an explicit instance of MyClass to work with in the event handler. Secondly, for simple events such as property change events, the meaning of the parameters is obvious and stated in the name of the event handler and I don't have to create a myriad of classes for these kinds of events.
The main difference will be that if you use Action<> your event will not follow the design pattern of virtually any other event in the system, which I would consider a drawback.
One upside with the dominating design pattern (apart from the power of sameness) is that you can extend the EventArgs object with new properties without altering the signature of the event. This would still be possible if you used Action<SomeClassWithProperties>, but I don't really see the point with not using the regular approach in that case.
The advantage of a wordier approach comes when your code is inside a 300,000 line project.
Using the action, as you have, there is no way to tell me what bool, int, and Blah are. If your action passed an object that defined the parameters then ok.
Using an EventHandler that wanted an EventArgs and if you would complete your DiagnosticsArgs example with getters for the properties that commented their purpose then you application would be more understandable. Also, please comment or fully name the arguments in the DiagnosticsArgs constructor.
I realize that this question is over 10 years old, but it appears to me that not only has the most obvious answer not been addressed, but that maybe its not really clear from the question a good understanding of what goes on under the covers. In addition, there are other questions about late binding and what that means with regards to delegates and lambdas (more on that later).
First to address the 800 lb elephant/gorilla in the room, when to choose event vs Action<T>/Func<T>:
Use a lambda to execute one statement or method. Use event when you
want more of a pub/sub model with multiple
statements/lambdas/functions that will execute (this is a major
difference right off the bat).
Use a lambda when you want to compile statements/functions to expression trees. Use delegates/events when you want to participate in more traditional late binding such as used in reflection and COM interop.
As an example of an event, lets wire up a simple and 'standard' set of events using a small console application as follows:
public delegate void FireEvent(int num);
public delegate void FireNiceEvent(object sender, SomeStandardArgs args);
public class SomeStandardArgs : EventArgs
{
public SomeStandardArgs(string id)
{
ID = id;
}
public string ID { get; set; }
}
class Program
{
public static event FireEvent OnFireEvent;
public static event FireNiceEvent OnFireNiceEvent;
static void Main(string[] args)
{
OnFireEvent += SomeSimpleEvent1;
OnFireEvent += SomeSimpleEvent2;
OnFireNiceEvent += SomeStandardEvent1;
OnFireNiceEvent += SomeStandardEvent2;
Console.WriteLine("Firing events.....");
OnFireEvent?.Invoke(3);
OnFireNiceEvent?.Invoke(null, new SomeStandardArgs("Fred"));
//Console.WriteLine($"{HeightSensorTypes.Keyence_IL030}:{(int)HeightSensorTypes.Keyence_IL030}");
Console.ReadLine();
}
private static void SomeSimpleEvent1(int num)
{
Console.WriteLine($"{nameof(SomeSimpleEvent1)}:{num}");
}
private static void SomeSimpleEvent2(int num)
{
Console.WriteLine($"{nameof(SomeSimpleEvent2)}:{num}");
}
private static void SomeStandardEvent1(object sender, SomeStandardArgs args)
{
Console.WriteLine($"{nameof(SomeStandardEvent1)}:{args.ID}");
}
private static void SomeStandardEvent2(object sender, SomeStandardArgs args)
{
Console.WriteLine($"{nameof(SomeStandardEvent2)}:{args.ID}");
}
}
The output will look as follows:
If you did the same with Action<int> or Action<object, SomeStandardArgs>, you would only see SomeSimpleEvent2 and SomeStandardEvent2.
So whats going on inside of event?
If we expand out FireNiceEvent, the compiler is actually generating the following (I have omitted some details with respect to thread synchronization that isn't relevant to this discussion):
private EventHandler<SomeStandardArgs> _OnFireNiceEvent;
public void add_OnFireNiceEvent(EventHandler<SomeStandardArgs> handler)
{
Delegate.Combine(_OnFireNiceEvent, handler);
}
public void remove_OnFireNiceEvent(EventHandler<SomeStandardArgs> handler)
{
Delegate.Remove(_OnFireNiceEvent, handler);
}
public event EventHandler<SomeStandardArgs> OnFireNiceEvent
{
add
{
add_OnFireNiceEvent(value)
}
remove
{
remove_OnFireNiceEvent(value)
}
}
The compiler generates a private delegate variable which is not visible to the class namespace in which it is generated. That delegate is what is used for subscription management and late binding participation, and the public facing interface is the familiar += and -= operators we have all come to know and love : )
You can customize the code for the add/remove handlers by changing the scope of the FireNiceEvent delegate to protected. This now allows developers to add custom hooks to the hooks, such as logging or security hooks. This really makes for some very powerful features that now allows for customized accessibility to subscription based on user roles, etc. Can you do that with lambdas? (Actually you can by custom compiling expression trees, but that's beyond the scope of this response).
To address a couple of points from some of the responses here:
There really is no difference in the 'brittleness' between changing
the args list in Action<T> and changing the properties in a class
derived from EventArgs. Either will not only require a compile
change, they will both change a public interface and will require
versioning. No difference.
With respect to which is an industry standard, that depends on where
this is being used and why. Action<T> and such is often used in IoC
and DI, and event is often used in message routing such as GUI and
MQ type frameworks. Note that I said often, not always.
Delegates have different lifetimes than lambdas. One also has to be
aware of capture... not just with closure, but also with the notion
of 'look what the cat dragged in'. This does affect memory
footprint/lifetime as well as management a.k.a. leaks.
One more thing, something I referenced earlier... the notion of late binding. You will often see this when using framework like LINQ, regarding when a lambda becomes 'live'. That is very different than late binding of a delegate, which can happen more than once (i.e. the lambda is always there, but binding occurs on demand as often as is needed), as opposed to a lambda, which once it occurs, its done -- the magic is gone, and the method(s)/property(ies) will always bind. Something to keep in mind.
On the most part, I'd say follow the pattern. I have deviated from it, but very rarely, and for specific reasons. In the case in point, the biggest issue I'd have is that I'd probably still use an Action<SomeObjectType>, allowing me to add extra properties later, and to use the occasional 2-way property (think Handled, or other feedback-events where the subscriber needs to to set a property on the event object). And once you've started down that line, you might as well use EventHandler<T> for some T.
If you follow the standard event pattern, then you can add an extension method to make the checking of event firing safer/easier. (i.e. the following code adds an extension method called SafeFire() which does the null check, as well as (obviously) copying the event into a separate variable to be safe from the usual null race-condition that can affect events.)
(Although I am in kind of two minds whether you should be using extension methods on null objects...)
public static class EventFirer
{
public static void SafeFire<TEventArgs>(this EventHandler<TEventArgs> theEvent, object obj, TEventArgs theEventArgs)
where TEventArgs : EventArgs
{
if (theEvent != null)
theEvent(obj, theEventArgs);
}
}
class MyEventArgs : EventArgs
{
// Blah, blah, blah...
}
class UseSafeEventFirer
{
event EventHandler<MyEventArgs> MyEvent;
void DemoSafeFire()
{
MyEvent.SafeFire(this, new MyEventArgs());
}
static void Main(string[] args)
{
var x = new UseSafeEventFirer();
Console.WriteLine("Null:");
x.DemoSafeFire();
Console.WriteLine();
x.MyEvent += delegate { Console.WriteLine("Hello, World!"); };
Console.WriteLine("Not null:");
x.DemoSafeFire();
}
}
Looking at Standard .NET event patterns we find
The standard signature for a .NET event delegate is:
void OnEventRaised(object sender, EventArgs args);
[...]
The argument list contains two arguments: the sender, and the event arguments. The compile time type of sender is System.Object, even though you likely know a more derived type that would always be correct. By convention, use object.
Below on same page we find an example of the typical event definition which is something like
public event EventHandler<EventArgs> EventName;
Had we defined
class MyClass
{
public event Action<MyClass, EventArgs> EventName;
}
the handler could have been
void OnEventRaised(MyClass sender, EventArgs args);
where sender has the correct (more derived) type.