Delegate and Event which execute/raised first? - c#

I don't know I should ask this question here or not But anyhow I am asking..
Suppose I have a asp button control, and I am using both Delegate and Click event for that button which will fire first?
On Init:
btn1.Click += delegate{ Save(); };
On Click Event:
protected void btn1_Click(object sender, EventArgs e)
{
Save1();
}
I want to know which will execute/raised first?

btn1_click is auto attached with click event in InitializeComponent() function at design time. InitializeComponent(0 function is called from constructor of form. It's default snippet of winforms.
You can not call the following statement before calling the InitializeComponent(), otherwise it will give error "Object reference not set to an instance of an object." Till this time the control is not intialised.
btn1.Click += delegate{ Save(); };
So the order of execution will be first the btn1_Click event and then the save function attached with delegate.

I think it has to do with the order in which they are assigned. Normally a method called btn1_Click will not fire until you bind it either in codebehind or in the ASPX file you are using.
I am guessing you are tying the btn1 to the btn1_Click method in the ASPX, that will probably fire first, but why not just test it? Put breakpoints on both lines and see which is hit first?

Event is not "executed", event is raised, so the execution will be of your event-handler which is btn1_Click on click esplicitly made by client.

Related

How is an event raised in C#?

My understanding about events in C# for a console application:
create a delegate that has the same signature as the event handler method in the subscriber class.
declare an event based on this delegate
raise the event
My understanding of this step is: it is simply an wrapper function where parameters are passed to the event to invoke the event handler functions pointed to by the event.
So raising the event is just invoking the wrapper function in the publish class.
Now when I create a very simple Windows form application, I am not able to apply this general concept.
Consider a WinForms application with just one button.
// registering statement
Button1.Click += new EventHandler (this.button1_click)
I can identify the first step. It is the pre-defined System.EventHandler delegate.
Click event for the button is also pre-defined. No problem with that.
event raising step : here I fail to make the connection between a console application and an Windows application.
Where is the code kept that actually RAISES the event for a WinForms application? We don't seem to have to code it.
I understand click event is raised when someone "clicks" on the button, but how is that realized in the C# code for WinForms application?
How does the compiler "just" knows that a Click event for a button means someone clicking on a button and therefore an event should be raised?
How is click event raised? How are the parameters passed to the event?
The Control class has protected function called WndProc, when the OS needs to tell the program something it generates a Message object and passes it in to the WndProc function.
That WndProc function then looks at the message and sees what kind of message it is, if it is the "mouse left button up" message it runs the the OnClick method with the correct parameters parsed out of the Message object that was passed in to WndProc.
That OnClick method is the thing that raises the event to the subscriber.
From the soruce of .NET:
The entry point of WndProc
It detecting the message type
It parsing and calling the OnClick method
It raising the Click event
Your understanding is a bit backwards. I think this is why you have issues.
You are not creating a delegate that has the same signature as the event handler method in the subscriber class.
What you are doing is declaring what a function to which to delegate execution will look like. Here is the signature for EventHandler:
public delegate void EventHandler(object sender, EventArgs e)
So, if you want a function to be able to handle delegation of the event, it must follow that signature.
Now, the class that will delegate execution to subscribers needs a reference to those functions so it can call them when the event takes place. That is why you implement an event property. It follows then that the Button class must expose this property for you to be able to "hook" your delegates:
public event EventHandler Click
(Notice this is inherited from Control)
When you register an "event handler":
Button1.Click += new EventHandler (this.button1_click)
You are essentially saying that you want this.button1_click(object sender, EventArgs e) to fire whenever the Click event is raised by the Button1 instance.
The Button1 instance will internally decide when to fire the event at which point it will use the event property to delegate execution to the subscribed functions. It will call them with the above mentioned parameters where sender will most likely be the instance itself and the EventArgs class will give you additional information about the conditions that raised the event. The property is also usually implemented to add additional checks (like if there is anything to call in the first place).
As you can see, the code that actually raises the click is internal to the implementation of the Button (or its inheritance chain). It obviously involves mouse tracking and what not, which is the benefit of using the controls by the way, unless you want to write all that detection stuff from scratch.

KeyUp - triggering twice

had the issue that my KeyUp and the KeyDown Event both fired twice when i invoked them. Finally found a fix for this:
this.glControl1.KeyUp -= this.glControl1_KeyUp;
this.glControl1.KeyUp += new KeyEventHandler(this.glControl1_KeyUp);
It works, but i really cant understand why. Could anyone explain me please.
Thank you
You probably have some repetitive event which you use as a trigger to hook up your event handler, a classic example is a button click e.g.
public void ButtonClick(object sender, EventArgs e)
{
this.SomeControl.KeyUp += this.SomeHandler;
}
The problem here is everytime the button is clicked the same event handler is assigned to the same event, there is nothing to prevent this from happening as it can be perfectly acceptable under certain circumstances.
To avoid this, you need to unhook the event handler before you reassign it, this is why executing the following line of code
this.SomeControl.KeyUp -= this.SomeHandler;
Before you assign the event handler prevents duplicate calls.

Handling Gridview.RowEdit

Quick one:
I've created
public event GridViewEditEventHandler invGridEdit {}.
Can I put code in this event to allow my end user to edit the DB entry, or do I need to point this to a new method for editing?
Edit: It's probably obvious that this is the first time I've looked at events. My apologies if this is a stupid question.
Check the documentation.
In general you have to register your own methods on specific events:
When you create a GridViewEditEventHandler delegate, you identify the
method that will handle the event. To associate the event with your
event handler, add an instance of the delegate to the event. The event
handler is called whenever the event occurs, unless you remove the
delegate. For more information about event-handler delegates, see
Events and Delegates.
In your case:
gridview.RowEditing += new GridViewEditEventHandler(myEditHandler);
Registered methods must have the signature your handler expects. In your case it's the delegate
public delegate void GridViewEditEventHandler(
Object sender,
GridViewEditEventArgs e
)
So the method myEditHandler looks like
void myEditHandler(Object sender, GridViewEditEventArgs e)
To access the firing gridview, perform a cast on sender:
GridView gv = (GridView)sender;
Your method is now called, if the event RowEditing is fired. This is the case, when:
The RowEditing event is raised when an Edit button (a button with its
CommandName property set to "Edit") is clicked, but before the
GridView control enters edit mode. This allows you to provide an
event-handling method that performs a custom routine, such as
canceling the edit operation, whenever this event occurs.
Hope it helps =)
Basically this is for any code you want to run to set up the editing on the grid.
From here:
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridviewediteventhandler(v=vs.110).aspx
The RowEditing event is raised when an Edit button (a button with its CommandName property set to "Edit") is clicked, but before the GridView control enters edit mode. This allows you to provide an event-handling method that performs a custom routine, such as canceling the edit operation, whenever this event occurs.
When you create a GridViewEditEventHandler delegate, you identify the method that will handle the event. To associate the event with your event handler, add an instance of the delegate to the event. The event handler is called whenever the event occurs, unless you remove the delegate. For more information about event-handler delegates, see Events and Delegates.

perform Click Event from a function for a specific button at a time?

I am creating a windows store application for which I have to program computer to perform a click on different button after the user has clicked a button. I have Implemented the logic for computer click. But the code b1.Click += btnClick; doesn't help me to perform a click event on the b1 button. Please tell how to do so. And please mention the namespace too if any extra to be used.
private void button6_Click(object sender, EventArgs e)
{
//just make sure your button initialized on form!!
this.button7.Click += new EventHandler(button7_Click);
EvenArgs ee = new EventArgs();
button7_Click(this.button7, ee); //this will fire button event!
}
b1.Click += btnClick; should work for subscribing to a button click event. When the user taps/clicks on the button, the btnClick handler will be fired.
Now, if I read your question properly, are you asking to perform a button click? If so, you can call the event handler btnClick yourself: btnClick(this, null);
b1.Click += btnClick;
b2.Click += btn2Click;
b3.Click += btn3Click;
void btnClick(...)
{
...
// perform a click on different button after the user has clicked a button.
btn2Click(...);
btn3Click(...);
}
As andrew says you should be able to add multiple events to an event handler like so:
b1.Click += btnClick1;
b1.Click += btnClick2;
For that^ you might want to check if the event handler is already attached to the event like this question explains.
Also as mentioned by both Andrew and Nagaraj you can just call the function from the event handler like:
btnClick2(this, null);
and it will execute the code ( albeit with a little less control since you won't be able to remove it from the click handler without a bunch of extra effort ).
Option three would be to create a function with the desired functionality you want for both buttons and just call that from both the handlers instead of making another button "click". It's more modular and obvious what is happening in your code then.

DataGridView and the CellEndEdit Event

I have a DataGridView, and would like to hook into the CellEndEdit event. I've been able to successfully hook into the CellContentClick event, but am having issues with CellEndEdit.
I added the following code to my Form1.cs file:
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellCancelEventArgs e)
{
dataGridView1[0, 0].Value = "Changed";
}
With that code, nothing happens when I am done editing a cell. Is there anything else that I need to do to successfully hook into this event? I see that CellContentClick has a
this.dataGridView1.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellContentClick);
line of code in the Form1.Designer.cs file, but I tried to mimic this for CellEndEdit, and received a compile error
(No overload for 'dataGridView1_CellEndEdit' matches delegate
'System.Windows.Forms.DataGridViewCellEventHandler')
You could implement this yourself.
In your constructor you could have a HookEvents() method which wires up such events.
Or, within the form designer, click the gridview to select it, go to the properties window and click the yellow thunderbolt to find a list of events. Then, scroll down and find the CellEndEdit event and double click it - this will wire up the event for you.
To wire it up yourself, it may look like:
class A : Form
{
public A()
{
Initialize();
HookEvents();
}
private void HookEvents()
{
dataGridView1.CellEndEdit += dataGridView1_CellEndEdit;
}
}
I doubt very much that your solution would work.
It's not a matter of where you place the subscription, is how you do it.
Brandon, you are declaring an EventHandler, that is the function responsible of doing what you want to do in case of that event "dataGridView1_CellEndEdit" but you are not subscribing to the event. Also in your function you are passing the wrong parameters.
The easy solution is either subscribe from the designer window or by code doing this:
write "dataGridView1.CellEndEdit +=" and then press the TAB buton twice. That shoud create the code for subscription to the event and the correct delegate to handle it.

Categories