I have a combobox in a custom control. How can I expose specific events from it such as SelectedIndexChanged or KeyPress, etc to anyone/thing implementing my custom control?
4 Answers
You can forward the events like this:
public event EventHandler SelectedIndexChanged
{
add { inner.SelectedIndexChanged += value; }
remove { inner.SelectedIndexChanged -= value; }
}

- 868,454
- 176
- 1,908
- 1,964
-
nice, didn't know such a syntax was available for events in C#. So you can also add side-effects there I guess for event handler assignment and removal (for example if you want to handle/maintain them yourself or need to do something with COM or native code or even with hardware when these happen) – George Birbilis Apr 04 '15 at 19:10
-
5You need to be careful with this as the sender of the event is not the outer control but the inner. This might be the intension but there are cases where this might be undesirable. – GDS May 06 '15 at 09:53
-
this may work fine for SelectedIndexChanged of a combobox but takes a bit more code to work for some other event like a checkbox's CheckedChanged. Using the code similar to above will get you syntax near value while answer #2 may work better for such cases – gg89 Jan 01 '17 at 00:33
-
@gg89: No; this will work for any possible event. You probably have the wrong delegate type; read the error message. – SLaks Jan 01 '17 at 03:51
-
may be I had the wrong type but the recommended approach for derived toolstripItem using controlhost is in the example in https://msdn.microsoft.com/en-us/library/system.windows.forms.toolstripcontrolhost(v=vs.110).aspx – gg89 Jan 01 '17 at 14:55
-
1@GDS why would that be undesirable? – Assimilater Jul 10 '17 at 17:11
-
Actually, thinking about it in the context of user controls it makes sense now (which is the OP, just not what I googled for). It's pretty common to have a list of MyControl and use the Sender property of an event to determine which control invoked your handler – Assimilater Jul 10 '17 at 17:14
You will need to code these into the control yourself - the user control does not automatically promote the events of its child controls. You can then cross-wire your actual control to the user control's promoted event:
public event EventHandler SelectedIndexChanged;
private void OnSelectedIndexChanged(object sender, EventArgs e)
{
if (SelectedIndexChanged != null)
SelectedIndexChanged(sender, e);
}
public UserControl1()
{
InitializeComponent();
cb.SelectedIndexChanged += new EventHandler(OnSelectedIndexChanged);
}
Unfortunately you will need to do this for every event you are interested in.

- 63,413
- 11
- 150
- 187
A very simple solution rather than having custom events, would be to expose the nested control as a property of the custom control. From there you could attach event handlers to it very easily. It is not always advisable to expose child controls, but depending on the control type and how you are using it, it may work.
//create an instance of my control
MyCustomControl controlInstance = new MyCustomControl();
//attach and event handler to the exposed subcontrol
controlInstance.SaveButton.Click += new EventHandler(SaveButton_Click);

- 13,218
- 3
- 40
- 60
-
4This is not incorrect, but for those readers not well-versed in creating custom User Controls it should be noted that one of the reasons its not advisable to expose child controls is that it defeats much of the intended purpose of the encapsulating a complete piece of functionality inside a User Control. By exposing an entire child control you are, in effect, encouraging the User Control consumer to manipulate the child control directly. Instead, try exposing the one or two events absolutely needed by your User Control's consumers, rather than the entire child control. – CobaltBlue Jul 13 '14 at 04:07
There is another way to handle that through the designer :
On the designer, in your custom control, on the combobox property under "Design" set "Modifiers" to internal.
Then where you need to to do something about it add :
CustControlName.YourCombo.SelectedIndexChanged += YourCombo_SelectedIndexChanged;
along with :
private void YourCombo_SelectedIndexChanged(object sender, EventArgs e)
{
// Code to execute when the SelectedIndexIsChanged goes here
}

- 57
- 11
-
works a little more conveniently but still subject to comment form CobaltBlue – gg89 Jan 01 '17 at 01:03