Event handler for a UserControl doesn't fire - c#

My UserControl contains various controls. I made an event handler for its click event. I want the event handler to fire / be called when the user clicks anywhere on my user control.
This is the method I use to add my UserControl to my WinForms application.
private void addContact(some parameters here)
{
//This is my usercontrol
contactsListItem.contactsListItem contact = new contactsListItem.contactsListItem();
//
//some codes here
//
//Adding an event handler for the click event
contact.Click += new EventHandler(contact_Click);
//Adding the UserControl to my application
flowLayoutPanel_contactsList.Controls.Add(contact);
}
The contact_Click(...) event handler should change the background of my UserControl. I have tried stepping into the code to see if the event handler fires and I found out that it doesn't fire no matter where I click on my UserControl.
I have searched through the internet. I encountered terms like delegate, subscribers and publishers.
What should I do to make the event handler for my UserControl's click event to fire?

What is the structure of your user control? Click events are not bubbled in WindForms, hence if you are clicking on a control WITHIN your user control, the latter won't fire any Click event.
EDIT:
The simplest solution is to manually bubble the event from each child by attaching a handler in your user control:
child1.Click += new EventHandler(child_Click);
child2.Click += new EventHandler(child_Click);
child3.Click += new EventHandler(child_Click);
and inside child_Click fire off your Click event:
this.OnClick(e);

You seem to be on the right track however it is not clear what your contact here is. Typically you use delegates (essentially pointers to functions) for methods that have arguments to be passed:
if (bDeleteRdClick)
DeleteRD.Click -= delegate { DeleteRDClick(this.Object); };
DeleteRD.Click += delegate { DeleteRDClick(this.Object); };
where you are sure to remove pre-existing delegates, otherwise they will 'stack-up', firing multiple methods when not required.
For the method above, using an EventHandler seems to me to be the right approach, but as I state above, a check on whether contact is of the correct type would not go unmissed:
if (this.contact.GetType() == typeof(RibbonButton))
{
RibbonButton Rb = (RibbonButton)contact;
Rb.Click += new EventHandler(contact_Click);
}
I hope this is of some help.

Related

C# how to unsubscribe all event handlers of a control (RadioButton)

I have a GUI that contains 10 radio buttons and a textbox, into which the user has to make his input. The RadioButton.CheckedChanged event gets subscribed on runtime depending on the user input (textbox). So, in my case there over 50 possible methods that can subscribe to the CheckedChanged event. Ok, I can unsubscribe every single method one by one (see excerpt from my code), but isn't there are any less time consuming and more efficent way to do this? Something like for instance:
unsubscribe all methods from the CheckedChanged event at once. Or: determine the method that currently subscribes to this event und unsubscribe this method.
I was already searching for an existing solution and found this: How to remove all event handlers from an event but in my case this solution does not works. As I mentioned, in my case there radio buttons, not normal buttons.
Excerpt from my code:
public List<RadioButton> RbList
public Form1()
{
InitializeComponent();
WindowState = FormWindowState.Maximized;
RbList = new List<RadioButton>
{
radioButton1, radioButton2, radioButton3, radioButton4, radioButton5, radioButton6, radioButton7,
radioButton8, radioButton9, radioButton10
};
}
private void Unsubscribe()
{
for (int i = 0; i < RbList.Count; i++)
{
RbList.ElementAt(i).CheckedChanged -= Method1;
RbList.ElementAt(i).CheckedChanged -= Method2;
...
}
}
Additional information regarding to the asked questions:
The last subscribed method does not get unsubscribed. With the radio buttons specific PDFs gets called. In the background is still the last subscribed method as long as another method is not get subscribed. So, if the user change the input in the textbox and the input does not matched anymore so that any other method can't be subscribed, the last method ist still there and the with the method associated PDFs can be accessed and that's exactly what I want to stop. I wouldn't have the problem, if the PDFs could by only accessed by clicking on the radio button. Then I could simply make all the radio buttons unvisible/unaccessible. But this is not the case, there is another option to the user to call the PDFs, which I dont mentioned - additionally there is a second textbox and if the input in this textbox is equal to the RadioButton.text the associated radio button gets also checked and the associated PDF to this radio button gets called and this is where the problem starts.

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.

How can several user controls respond to an event that occurs in one of them in c#?

I have a user control that consists of a checkbox. I have 4 of these user controls on a form. When the user clicks any one of the checkboxes in the user control, I want the other user controls to ensure they are not checked. Similar to the way that radio buttons would work, except I need to use checkboxes and events.
A simple way could be use a single method for all the events of the CheckBoxes and exploit the sender object in this way:
List<CheckBox> listCheckBoxes;
checkBox1.CheckedChanged += new EventHandler(checkBox_CheckedChanged);
checkBox2.CheckedChanged += new EventHandler(checkBox_CheckedChanged);
checkBox3.CheckedChanged += new EventHandler(checkBox_CheckedChanged);
checkBox4.CheckedChanged += new EventHandler(checkBox_CheckedChanged);
listCheckBoxes = this.Controls.OfType<CheckBox>().ToList();
void checkBox_CheckedChanged(object sender, EventArgs e){
CheckBox checkBox = (CheckBox)sender;
if(checkBox.Checked){
foreach(CheckBox c in listCheckBoxes){
if(c.Checked && c != checkBox)
c.Checked = false;
}
}
}
The event handler is typically a method of the form (or a custom container). You typically know about other controls at that level. If you're trying to execute that event handler on the custom control itself you're going to have issues because you'll be tying the control to other controls.
It would be a better design to have some sort of container control that has an event handler to perform this logic. That event handler would then be added to the Click event of each of the checkboxes.
Wrap up the controls in a single UserControl. When an event fires on a single CheckBox control raise a general toggle event for the remaining CheckBox controls.
OK , if i am assuming right . you got 4 usercontrols in a form and they need to communicate with each other on some event ( in your case it is event caused by checkbox in one of your user control)
I would implement subscriber /publisher model.
In Usercontrol-A (publisher)
1) On checkbox click raise a event , forward this to a common event function
Page class which contains the usercontrol , will subscribe to the event of UsercontrolA and if required forward it to Usercontrol B (subscriber)
for more details see this
http://www.codeproject.com/Articles/15550/How-to-invoke-events-across-User-Controls-in-ASP-N

C#: Multiple Event Raises

My question is related to events:
I have Class with a TaskAComplete Event that is raised when TaskA is complete.
When a button is pressed I subscribe the TaskACompleteEvent
MyObject.TaskAComplete += new EventHandler(MethodToCall);
But in other Event I want to Unsubscribe from the TaskAComplete Event when the Event occurs the first time.
with:
MyObject.TaskAComplete -= MethodToCall;
And then when the Button is pressed the next time to Subscribe the TaskAComplete Event again.
Now when i start the Application and click on the Button the first time it raises the Event correctly.But when i click on the Button the second time the Event is raises two times in a row. (Third time click ->Event is raised three times in a row and so on..)
When i Subscribe the Event in the Contructor of the Form it only raises one time at every click.
Why the Event comes several times?
When you subscribe to an event, you are subscribing by providing a delegate to a method. A delegate is effectively a strongly-typed, object-oriented approach to a C/C++ function pointer.
This delegate then goes into the list of calls for the event.
When you do new EventHandler(MethodToCall) you are explicitly creating that delegate. However, when you do -= MethodToCall, you are removing an "automatic" delegate. It is as if you wrote -= new EventHandler(MethodToCall). Obviously, this new delegate is not the one in the invocation list.
To do what you want, on add, you need to save the new delegate in a variable, which you can later remove. For example:
var handler = new EventHandler(MethodToCall);
MyObject.TaskAComplete += handler;
// later on
MyObject.TaskAComplete -= handler;
You only need to subscribe to the event once. If you subscribe multiple times with the same handler, that handler will be invoked multiple times just like you are seeing.
Why do you want to unsubscribe from the TaskAComplete event in the first place? If your other code is correct, you will get it exactly once for each task.

Custom Event on Custom Control

I've got a custom control we'll call "TheGrid".
In TheGrid's controls is another control we'll call "GridMenu".
GridMenu has a button control in its own control collection.
I'd like to enable the developer using this control to associate a page level method with the OnClick of that button deep down inside GridMenu ala:
<customcontrols:TheGrid id="tehGridz" runat="server" onGridMenuButtonClick="mypagemethod" />
On the GridMenu (which I assume is another custom control), expose the event ButtonClick by declaring it as public:
public event EventHandler ButtonClick;
If you like, you can create a custom event handler by defining a delegate, and a custom event argument class. Somewhere in the logic of this control, you will need to raise the event (perhaps in the Clicked event handlers of buttons contained on GridMenu; events can cascade). Coding in C#, you'll need to check that the event is not null (meaning at least one handler is attached) before raising the event.
Now this event is visible to TheGrid, which contains your GridMenu. Now you need to create a "pass-through" to allow users of TheGrid to attach handlers without having to know about GridMenu. You can do this by specifying an event on TheGrid that resembles a property, and attaches and detaches handlers from the inner event:
public event EventHandler GridMenuButtonClick
{
add{ GridMenu.ButtonClick += value;}
remove { GridMenu.ButtonClick -= value;}
}
From the markup of a control containing a TheGrid control, you can now specify the event handler by attaching it to OnGridMenuButtonClicked the way you wanted.
You can register an event handler for this event using delegates. See the following MSDN articles:
http://msdn.microsoft.com/en-us/library/system.eventhandler%28VS.71%29.aspx
http://msdn.microsoft.com/en-us/library/aa720047%28v=VS.71%29.aspx

Categories