Click here to Skip to main content
15,892,746 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
How do i raise an event in a usercontrol and catch it in another user Control?
Posted
Comments
BillWoodruff 23-Mar-15 6:15am    
In general, any instance of a Form, or UserControl, can subscribe to an Event Handler exposed as 'public in another Form, or UserControl, instance.

If you give more details about what your goal is here, I'll be happy to respond further. What is important is where (in what Form or UserControl) the UserControl instances are created, and whether they are created at run-time or design-time.

Also, if you are using inheritance, or Interfaces, that's important to know.

Please also state if this is Windows Forms.
Sarita S 23-Mar-15 6:22am    
This is windows form application.I have 2 user control(say UserControl1 and USerControl2) added to the main form.Now problem is that UserControl1 have textbox and I want to access this textbox text from UserControl2.But I couldnot fire the textbox_textchanged event of UserControl1 to UserControl2.
Sarita S 23-Mar-15 6:27am    
I tried it by creating Custom Event handler.
userControl1
{
private event EventHandler titleChanged;
textbox_textChanged(sender,e)
{
titleChanged(sender,e);
}
}

UserControl2
{
UserControl2()
{
UserControl1.titleChanged + = new EventHandler(onTitleChanged)
}
public void onTitleChanged(sendr,e)
{
//Code to access the textbox tex
}
}
}
}
But could not access the textbox data.
Sinisa Hajnal 23-Mar-15 7:06am    
Why not? What type is the sender? Why not create your own EventArg? Say TitleChangedEventArgs which would contain Title property. Then you could just do e.Title in event handler

For this kind of "dedicated event/message passing" I prefer to use the 'Action delegate Type:
C#
// in UserControl1:
public Action<string> OnTitleChanged;

private void textBox1_TextChanged(object sender, EventArgs e)
{
   if(OnTitleChanged != null) OnTitleChanged(textBox1.Text);
}

// in UserControl2:
public void SetText(string theText)
{
    textBox1.Text = theText;
}

// in the Form that creates instances of the UserControls:
private void Form1_Load(object sender, EventArgs e)
{
    userControl1Instance.OnTitleChanged = userControl2Instance.SetText;
}</string>
Notes:

1. An Action<> (or a Func<>) is a full-featured Delegate Type; they are capable of having multiple subscribers which can be set, or removed, using += and -= syntax.

2. By directly assigning a reference to a method (whose Type parameters match the Action specification) ... rather than using +=, you essentially "dedicate" this Action to one purpose, which is passing a string to whatever method it encapsulates.

I believe this usage is a good thing, because:

a. it is simplifying: you get the "good parts" of an Event/EventHandler without the need to create Custom EventArguments, etc.

b. imho, the use of this "pattern" is communicates the intent of the programmer to have a "dedicated Event/EventHandler" that does "one thing."

3. imho, this "pattern" should not be used where you are publishing your code with the expectation that end-users may create multiple subscribers to it ... although that could be used without error with Action, or Func.
 
Share this answer
 
Comments
OriginalGriff 23-Mar-15 8:43am    
Who gave you a one? It wasn't there when I upvoted it (or I'd have upvoted it in compensation, instead of because it's a good solution). Not a "high roller", anyway.
Basically, you shouldn't be doing it like that: one control shouldn't know about the existence of the other. If they do, then you "lock" the two controls together, and you can't use them independently for any other purpose.

Instead, your form should handle the Event from Control1, fetch the data from it, and pass it to Control2 via a Property or Method. Since the Form contains both controls, it has to know about their existence, so that's all fine.

There is an example here: Transferring information between two forms, Part 3: Child to Child[^] - it's about Forms, but Controls should behave in exactly the same way.
 
Share this answer
 
Comments
Sarita S 23-Mar-15 7:09am    
Thank u so much.Given Link cleared all doubt
OriginalGriff 23-Mar-15 7:24am    
You're welcome!
BillWoodruff 23-Mar-15 8:16am    
Hi, OG, I am curious to ask you if you believe the solution I posted here meets your criterion: "one control shouldn't know about the existence of the other."

I am sure you know I ask this without any intent of "beating my own drum" :)

thanks, Bill
OriginalGriff 23-Mar-15 8:42am    
Yes it does - and it's a good solution.
The only things I don't like are relatively trivial:
1) You should probably change
if(OnTitleChanged != null) OnTitleChanged(textBox1.Text);
to
Action<string> temp = OnTitleChanged;
if(temp != null) temp(textBox1.Text);
So that it can't fail if the action is removed - unlikely, but it's no real overhead for a little benefit. (Chances are the optimizer will do this anyway and generate the same code for both fragment, but I believe in checking rather than relying on exceptions)
2) It's a bit advanced for beginners - and this guy strikes me as a beginner! :laugh:
3) It doesn't allow chaining in the way an event does. (Most of the time this is immaterial, but every now and then...)
BillWoodruff 23-Mar-15 8:51am    
Thanks for the feedback, and the vote, OG. When I first discovered that Action and Func allowed use of += and -= I was surprised, although, when I got over the surprise, I realized that I should have expected that because they are, in fact, first-class Delegates.

When you say "doesn't allow chaining," I am not sure exactly what you mean; could you expand on that a bit ?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900