86

I have a custom usercontrol and I want to do something relatively simple.

When ever a numeric up down in that usercontrol's value changes, have the main form update a display window.

This is not a problem if the NUD was not in a usercontrol but I can't seem to figure out how to have the event handled by the mainform and not the usercontrol.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Crash893
  • 11,428
  • 21
  • 88
  • 123
  • 1
    possible duplicate of [Winforms user controls custom events](http://stackoverflow.com/questions/2188059/winforms-user-controls-custom-events) – John Saunders Oct 24 '11 at 19:34

5 Answers5

156

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.

Matt
  • 25,467
  • 18
  • 120
  • 187
James Johnson
  • 45,496
  • 8
  • 73
  • 110
  • I am having trouble getting this to work on user control instances that are inside repeater control that generates them on the OnItemDatabound event. It is as if the `UserControl1.ButtonClick += new EventHandler(UserControl_ButtonClick);` part is not doing anything. `if (this.ButtonClick!= null)` always returns false. – Osprey May 28 '17 at 14:24
  • 1
    @Osprey: Inside of a repeater, you would probably want to add the handler declaratively in the markup, e.g. ``. Otherwise, you would need to find the user control during data binding of the repeater and attach the event handler there. – James Johnson Jun 02 '17 at 19:34
28

Try mapping it. Try placing this code in your UserControl:

public event EventHandler ValueChanged {
  add { numericUpDown1.ValueChanged += value; }
  remove { numericUpDown1.ValueChanged -= value; }
}

then your UserControl will have the ValueChanged event you normally see with the NumericUpDown control.

LarsTech
  • 80,625
  • 14
  • 153
  • 225
14

you can do like this.....the below example shows text box(user control) value changed

   // Declare a delegate 
public delegate void ValueChangedEventHandler(object sender, ValueChangedEventArgs e);
public partial class SampleUserControl : TextBox 
{    
    public SampleUserControl() 
    { 
        InitializeComponent(); 
    }

    // Declare an event 
    public event ValueChangedEventHandler ValueChanged;

    protected virtual void OnValueChanged(ValueChangedEventArgs e) 
    { 
        if (ValueChanged != null) 
            ValueChanged(this,e); 
    }    
    private void SampleUserControl_TextChanged(object sender, EventArgs e) 
    { 
        TextBox tb  = (TextBox)sender; 
        int value; 
        if (!int.TryParse(tb.Text, out value)) 
            value = 0; 
        // Raise the event 
       OnValueChanged( new ValueChangedEventArgs(value)); 
    }    
}
Glory Raj
  • 17,397
  • 27
  • 100
  • 203
0

one of the easy way to do that is use landa function without any problem like

userControl_Material1.simpleButton4.Click += (s, ee) =>
            {
                Save_mat(mat_global);
            };
0

For those looking to do this in VB, here's how I got mine to work with a checkbox.

Background: I was trying to make my own checkbox that is a slider/switch control. I've only included the relevant code for this question.

In User control MyCheckbox.ascx

<asp:CheckBox ID="checkbox" runat="server" AutoPostBack="true" />

In User control MyCheckbox.ascx.vb

Create an EventHandler (OnCheckChanged). When an event fires on the control (ID="checkbox") inside your usercontrol (MyCheckBox.ascx), then fire your EventHandler (OnCheckChanged).

Public Event OnCheckChanged As EventHandler

Private Sub checkbox_CheckedChanged(sender As Object, e As EventArgs) Handles checkbox.CheckedChanged
    RaiseEvent OnCheckChanged(Me, e)
End Sub

In Page MyPage.aspx

<uc:MyCheckbox runat="server" ID="myCheck" OnCheckChanged="myCheck_CheckChanged" />

Note: myCheck_CheckChanged didn't fire until I added the Handles clause below

In Page MyPage.aspx.vb

Protected Sub myCheck_CheckChanged (sender As Object, e As EventArgs) Handles scTransparentVoting.OnCheckChanged
    'Do some page logic here
End Sub
Tony L.
  • 17,638
  • 8
  • 69
  • 66
  • I know you answered this 2 years ago, but the question was in regards to WinForms, and not ASP.Net - while the general idea is similar (using event handlers) the implementation in WinForms would be different – Justin Greywolf Jul 02 '22 at 03:51