How can I invoke (web) Button.Click in c#? - c#

As the title really, I'm in one part of my code and I would like to invoke any methods that have been added to the Button.Click handler.
How can I do this?

Do you mean you need to access it from elsewhere in your code? It may be an idea to refactor that section to it's own method then call that method whenever you need to access it (including in the Click event)

AVOID. Really. Seems like you handle some important logic right in the event handler.
Move the logic out of the handler.

You can do it via reflection..
Type t = typeof(Button);
object[] p = new object[1];
p[0] = EventArgs.Empty;
MethodInfo m = t.GetMethod("OnClick", BindingFlags.NonPublic | BindingFlags.Instance);
m.Invoke(btnYourButton, p);

You will need an event to act as a proxy, but you are pretty much better off just refactoring your code.
private EventHandler ButtonClick;
protected override void CreateChildControls()
{
base.CreateChildControls();
m_Button = new Button{Text = "Do something"};
m_Button.Click += ButtonClick;
ButtonClick += button_Click;
Controls.Add(m_Button);
}
private void MakeButtonDoStuff()
{
ButtonClick.Invoke(this, new EventArgs());
}
private void button_Click(object sender, EventArgs e)
{
}
Do not do this if you really dont need it. It will make a mess of your code.

Related

How to easilly see number of event subscriptions while debugging?

While debugging, can I look into textBox1.TextChanged to see the number of event subscriptions? If yes, then how do I drill to it? I need to know how many subscriptions there are at a given time for debugging because it looks like an event is triggered multiple times, but I suspect this bug is really because textBox1.TextChanged += handler is being mismanaged in the application, so there are too many subscribers.
Here is a simplified version of what I think is happening. If possible, I just want to set a breakpoint and count up the number of subscriptions to "textBox1.TextChanged":
private void textBox1_TextChanged(object sender, EventArgs e)
{
textBox1.TextChanged += textBox1_TextChanged;
MessageBox.Show("asdf");
textBox1.TextChanged -= textBox1_TextChanged;
textBox1.Text = DateTime.Now.ToString();
textBox1.TextChanged += textBox1_TextChanged;
}
Is that possible or is it more complicated?
If you're only concerned with doing it under the debugger, rather than programmatically, then this is perhaps a simpler, non-invasive way:
class _24003458
{
event EventHandler MyEvent;
public void Test()
{
MyEvent += Handler1;
MyEvent += Handler2;
MyEvent(this, EventArgs.Empty);
}
void Handler1(object sender, EventArgs e)
{
throw new NotImplementedException();
}
void Handler2(object sender, EventArgs e)
{
throw new NotImplementedException();
}
}
Put a breakpoint on either of the event handlers, and when it breaks, look at the Locals tab. The event, when expanded, will show the invocation count and event handlers:
You will have to use Reflection to get to the invocation list of the event delegate:
textBox1.TextChanged += textBox1_TextChanged;
MessageBox.Show("asdf");
textBox1.TextChanged -= textBox1_TextChanged;
textBox1.Text = DateTime.Now.ToString();
textBox1.TextChanged += textBox1_TextChanged;
var eventField = textBox1.GetType().GetField("TextChanged", BindingFlags.GetField
| BindingFlags.NonPublic
| BindingFlags.Instance);
var subscriberCount = ((EventHandler)eventField.GetValue(textBox1))
.GetInvocationList().Length;
It is not possible with an event like this (for good reason), however, it is possable via reflection as Selman22 says, above) if you are using an event directly you can do so:
private event EventHandler handler;
var delegates = handler.GetInvocationList();
You can create a member method which you add to the object which implements the INotifyPropertyChanged interface. It makes debugging very easy:
#if DEBUG
public System.Delegate[] GetInvocationList()
{
return PropertyChanged?.GetInvocationList();
}
#endif

What's the difference between the Click event and a user defined event in C#

I'm trying to understand events better, and i've seen some lines of code that made me confused..
I know that, for example, when I want to declare an event and later subscribe to it i will do like this:
public event EventHandler MyEvent;
...
MyEvent += MyFunction;
MyEvent += new SomeClass().SomeFunction;
So here I declared the event and subscrbed some functions to it. It's easy.
Later I found this piece of code:
protected void Page_Load(object sender, EventArgs e)
{
for(int i =0; i<5; i++)
{
Button btn = new Button();
btn.Text = "Button " + i.ToString();
Panel1.Controls.Add(btn);
btn.Click += new EventHandler(this.BtnFunction);
}
}
void BtnFunction(object sender, EventArgs e)
{
Button btn = (Button)sender;
Label1.Text = btn.Text;
}
Now what I can't understand is this line here: btn.Click += new EventHandler(this.BtnFunction);
The questions are:
Why do I use the new EventHandler(this.BtnFuncion)? Isn't the Click event of a type EventHandler?
Does EventHandler have a constructor and why does it takes now the function that should subscribe to this event?
.Net BCL's event and User defined event are not different. Click Event is like the following:
public event EventHandler Click;
EventHandler is a delegate type, which is used in .Net BCL's event. I think you have seen some event handlers, like void function(object sender, EventArgs e). EventHandler is like the follwing:
public delegate void EventHandler(object sender, EventArgs e);
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
The second delegate, EventHandler<TEventArgs> is used when event required to send some information. For example:
public event EventHandler<SomeClass> MyEvent;
edit: Notice that SomeClass is recommended to inherit EventArgs for covariance
There is no difference. This is called syntax sugar. You don't have to help because the compiler can figure out that you meant to use a delegate. This sugar is important because without it you would have to write this to unsubscribe the event:
btn.Click -= new EventHandler(this.BtnFunction);
Which sets off major alarm bells to an unsuspecting new C# programmer that's learning the language: "Create a new delegate to remove an event handler??" Yes. Really. Nobody blows a fuse over:
btn.Click -= this.BtnFunction;
Even the delegate constructor call is syntax sugar, it actually requires two arguments under the hood. One that sets the Target property and another that sets the Method. The target is inferred by the compiler, it is this. The two argument constructor syntax is not legal in C#, a language like C++/CLI has it.
This is the short notation of assign an Event Handler:
MyEvent += MyFunction;
And this is the long notation:
btn.Click += new EventHandler(this.BtnFunction);
This line can be written like this:
btn.Click += this.BtnFunction;

How to check if the object already has the a specify event set

I have a class named MifareReader. I instantiate it as Global So i Have on my form_load:
MifareReader mf = new MifareReader()
private void Main_Load(object sender, EventArgs e)
{
mf.MyEvent += new EventName(My_Method);
Connect();
}
private void My_Method()
{
//Code Here
}
private void Connect()
{
//Some Code Here
mf.MyEvent += new EventName(My_Method); //The same code of the Main_Load
}
Now let me explain. On my Main_Load I've set the event MyEvent and set it's method to My_Method Right ? Also, I called the other method Connect(), this methods repeat what i've done on the Main_Load
mf.MyEvent += new EventName(My_Method);
Right ?
So, I don't know why, but if I do not repeat this code, the application DOES NOT fire the MyEvent without Closing/Reopening the application.
Ok, its working perfect the way it is, but when I close/reopen my application, it fires MyEvent twice. So, Is there a way to work around this ?
Maybe check if the mf.MyEvent has already a method set to it?

Trigger control's event programmatically

Assume that I have a WinFoms project. There is just one button (e.g. button1).
The question is: is it possible to trigger the ButtonClicked event via code without really clicking it?
Button controls have a PerformClick() method that you can call.
button1.PerformClick();
The .NET framework uses a pattern where for every event X there is a method protected void OnX(EventArgs e) {} that raises event X. See this Msdn article. To raise an event from outside the declaring class you will have to derive the class and add a public wrapper method. In the case of Button it would look like this:
class MyButton : System.Windows.Forms.Button
{
public void ProgrammaticClick(EventArgs e)
{
base.OnClick(e);
}
}
You can just call the event handler function directly and specify null for the sender and EventArgs.Empty for the arguments.
void ButtonClicked(object sender, EventArgs e)
{
// do stuff
}
// Somewhere else in your code:
button1.Click += new EventHandler(ButtonClicked);
// call the event handler directly:
ButtonClicked(button1, EventArgs.Empty);
Or, rather, you'd move the logic out of the ButtonClicked event into its own function, and then your event handler and the other code you have would in turn call the new function.
void StuffThatHappensOnButtonClick()
{
// do stuff
}
void ButtonClicked(object sender, EventArgs e)
{
StuffThatHappensOnButtonClick();
}
// Somewhere else in your code:
button1.Click += new EventHandler(ButtonClicked);
// Simulate the button click:
StuffThatHappensOnButtonClick();
The latter method has the advantage of letting you separate your business and UI logic. You really should never have any business logic in your control event handlers.
Yes, just call the method the way you would call any other. For example:
private void btnSayHello_Click(object sender, EventArgs e)
{
MessageBox.Show("Hello World!");
}
private void btnTriggerHello_Click(object sender, EventArgs e)
{
btnSayHello_Click(null, null);
}
button1.PerformClick();
But if you have to do something like this maybe it's better to move the code you have under the event on a new method ?
Why don't you just put your event code into a Method. Then have the Event execute the method. This way if you need to execute the same code that the Event rises, you can, but simply just calling the "Method".
void Event_Method()
{
//Put Event code here.
MessageBox.Show("Hello!");
}
void _btnSend_Click(object sender, EventArgs e)
{
Event_Method();
}
void AnotherMethod()
{
Event_Method();
}
Make sense? Now the "Click" event AND anywhere in code you can trigger the same code as the "Click" event.
Don't trigger the event, call the method that the event calls. ;)
In most cases you would not need to do that. Simply wrap your functionality in functions related to a specific purpose (task). You call this function inside your event and anywhere else it's needed.
Overthink your approach.
I recently had this problem where I wanted to programatically click a button that had multiple event handlers assigned to it (think UserControl or derived classes).
For example:
myButton.Click += ButtonClicked1
myButton.Click += ButtonClicked2;
void ButtonClicked1(object sender, EventArgs e)
{
Console.WriteLine("ButtonClicked1");
}
void ButtonClicked2(object sender, EventArgs e)
{
Console.WriteLine("ButtonClicked1");
}
When you click the button, both functions will get called. In the instances where you want to programmatically fire an event handler for a function from a form (for example, when a user presses enter in a Text field then call the InvokeOnClick method passing through the control you. For example
this.InvokeOnClick(myButton, EventArgs.Empty);
Where this is the Form instance you are in.
use a for loop to call the button_click event
private void btnadd_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i <= 2; i++)
StuffThatHappensOnButtonClick();
}
void StuffThatHappensOnButtonClick()
{
........do stuff
}
we assume at least one time you need click the button

how do I parameterize an event, in c#

i want to redefine an event, i mean, i have this:
boton.Click += infoApp;
//i think thats similar to: boton.Click = new System.EventHandler(infoApp).
when button 'boton' is clicked, the function/method 'infoApp' triggers,
this method its something like this:
private void infoApp(object sender, EventArgs e)
{
/* my code*/
}
Until here, evetithing goes well; but I NEED to send another parameter to that method:
boton.Click += infoApp(string par)
so i thought that this could work:
private void infoApp(object sender, EventArgs e, string par)
{
/*My code*/
}
but it doesn't.
I've readen things like delegates but i don't understand; and i dont know what to do in order to solve my problem; any ideas?
Thanks in advance
pd: sorry by my terrible english, i'm not english speaker. Try to be simple explaining. I'm using VS2008.
One way you could solve this, would be to wrap your event handler in a closure:
Instead of this line:
boton.Click += infoApp;
Do this:
string par = "something";
boton.Click += (sender, e) => {
//Now call your specific method here:
infoApp(sender, e, par);
};

Categories