How to Add an Event to a Usercontrol in C#

How to add an event to a UserControl in C#?

First, you need to declare the event within your class (alongside your methods and constructors):

public event EventHandler LabelsTextChanged;

Then you need to create a method to handle the individual labels' TextChanged events.

private void HandleLabelTextChanged(object sender, EventArgs e)
{
// we'll explain this in a minute
this.OnLabelsTextChanged(EventArgs.Empty);
}

Somewhere, probably in your control's constructor, you need to subscribe to the label's TextChanged events.

myLabel1.TextChanged += this.HandleLabelTextChanged;
myLabel2.TextChanged += this.HandleLabelTextChanged;
myLabel3.TextChanged += this.HandleLabelTextChanged;

Now for the HandleLabelsTextChanged method. We could raise LabelsTextChanged directly; however, the .NET framework design guidelines say that is it a best practice to create an OnEventName protected virtual method to raise the event for us. That way, inheriting classes can "handle" the event by overriding the OnEventName method, which turns out to have a little better performance than subscribing to the event. Even if you think you will never override the OnEventName method, it is a good idea to get in the habit of doing it anyway, as it simplifies the event raising process.

Here's our OnLabelsTextChanged:

protected virtual void OnLabelsTextChanged(EventArgs e)
{
EventHandler handler = this.LabelsTextChanged;
if (handler != null)
{
handler(this, e);
}
}

We have to check for null because an event without subscribers is null. If we attempted to raise a null event, we would get a NullReferenceException. Note that we copy the event's EventHandler to a local variable before checking it for null and raising the event. If we had instead done it like this:

if (this.LabelsTextChanged != null)
{
this.LabelsTextChanged(this, e);
}

We would have a race condition between the nullity check and the event raising. If it just so happened that the subscribers to the event unsubscribed themselves just before we raised the event but after we checked for null, an exception would be thrown. You won't normally encounter this issue, but it is best to get in the habit of writing it the safe way.

Edit: Here is how the public event EventHandler LabelsTextChanged; line should be placed:

namespace YourNamespace
{
class MyUserControl : UserControl
{
// it needs to be here:
public event EventHandler LabelsTextChanged;

...
}
}

Here are the framework design guidelines on event design for further reading.

How do I make an Event in the Usercontrol and have it handled in the Main Form?

You need to create an event handler for the user control that is raised when an event from within the user control is fired. This will allow you to bubble the event up the chain so you can handle the event from the form.

When clicking Button1 on the UserControl, i'll fire Button1_Click which triggers UserControl_ButtonClick on the form:

User control:

[Browsable(true)] [Category("Action")] 
[Description("Invoked when user clicks button")]
public event EventHandler ButtonClick;

protected void Button1_Click(object sender, EventArgs e)
{
//bubble the event up to the parent
if (this.ButtonClick!= null)
this.ButtonClick(this, e);
}

Form:

UserControl1.ButtonClick += new EventHandler(UserControl_ButtonClick);

protected void UserControl_ButtonClick(object sender, EventArgs e)
{
//handle the event
}

Notes:

  • Newer Visual Studio versions suggest that instead of if (this.ButtonClick!= null) this.ButtonClick(this, e); you can use ButtonClick?.Invoke(this, e);, which does essentially the same, but is shorter.

  • The Browsable attribute makes the event visible in Visual Studio's designer (events view), Category shows it in the "Action" category, and Description provides a description for it. You can omit these attributes completely, but making it available to the designer it is much more comfortable, since VS handles it for you.

Custom event in a user control

You just need to raise your custom event from the _bsMyBindingSource_ListChanged handler.

You can keep it as a ListChangedEventHandler:

public class MyUserControl : UserControl
{
public event ListChangedEventHandler OnChange;

private void _bsMyBindingSource_ListChanged(object sender, ListChangedEventArgs e)
{
// if no listeners, OnChange will be null, so need to check
if(this.OnChange != null)
{
this.OnChange(this, e);
}
}
}

Or do a custom event type:

public class MyUserControl : UserControl
{
public event EventHandler OnChange;

private void _bsMyBindingSource_ListChanged(object sender, ListChangedEventArgs e)
{
// if no listeners, OnChange will be null, so need to check
if(this.OnChange != null)
{
this.OnChange(this, new EventArgs());
}
}
}

Then your page or whatever can listen to this event:

public class MyPage : Page
{
private MyUserControl myControl;

public void MyPage_Load()
{
myControl.OnChange += myControl_OnChange;
}

private void myControl_OnChange(object sender, ListChangedEventArgs e)
{
// ... do something
}
}

How do I raise an event in a usercontrol and catch it in mainpage?

Check out Event Bubbling -- http://msdn.microsoft.com/en-us/library/aa719644%28vs.71%29.aspx

Example:

User Control

public event EventHandler StatusUpdated;

private void FunctionThatRaisesEvent()
{
//Null check makes sure the main page is attached to the event
if (this.StatusUpdated != null)
this.StatusUpdated(this, new EventArgs());
}

Main Page/Form

public void MyApp()
{
//USERCONTROL = your control with the StatusUpdated event
this.USERCONTROL.StatusUpdated += new EventHandler(MyEventHandlerFunction_StatusUpdated);
}

public void MyEventHandlerFunction_StatusUpdated(object sender, EventArgs e)
{
//your code here
}

How to create a textchange event for usercontrol

Please see this answer on how to create a custom event in WPF.

Following this approach, you can handle the "TextChanged" event for the textbox inside your user control, then raise a custom event from there.

how do I subscribe to an event of a usercontrol

UserControl1.Changed += UserControl1_Changed;

Update your control to include the following:

// A delegate type for hooking up change notifications.
// This is _what kind_ of event you want. It sets the signature your event handler methods must have.
public delegate void ChangedEventHandler(object sender, EventArgs e);

//the actual event
public event ChangedEventHandler Changed;

// Method to raise/fire the Changed event. Call this whenever something changes
protected virtual void OnChanged(EventArgs e)
{
ChangedEventHandler handler = Changed;
if (handler != null) handler(this, e);
}

//and update your existing SetValue() function like so:
public void SetValue(string aValue)
{
txtValue.Text = aValue;
OnChanged(EventArgs.Empty);
}

You can change your event signature to pass any information you want — for example the old or new value of the property (or both). I just used the standard event arguments for the example.

And speaking or properties, don't write separate Get/Set methods in C# like you just did. If you find yourself doing that, you probably want to use a property instead, which will enforce the correct get/set semantics automatically:

public string Value 
{
get { return txtValue.Text;}
set {txtValue.Text = value; OnChanged(EventArgs.Emtpy); }
}


Related Topics



Leave a reply



Submit