views:

63

answers:

4

I have a listbox inside a custom control. I use this custom control into a form. I would like to be able to get the listbox index changed event when I am working into the form. How can I do that?

+4  A: 

If you are using WinForms, then you need to wire this event manually. Create event with the same signature on your custom control, create a handler for the even on the original listbox inside your custom control and in this handler fire the newly created event. (ignore all of this if you are using WPF)

Grzenio
Yes I use WinForm, an example would be useful
Wildhorn
+3  A: 

You can add a proxy event to the custom control

public event EventHandler<WhatEverEventArgs> IndexChanged { 
    add { listBox.IndexChanged += value; }
    remove { listBox.IndexChanged -= value; } 
}
Arne
+1 Event properties seems to be a little-known feature. In addition to this situation, they are useful for storing event handler delegates in an EventHandlerList (which is typically what the built-in controls do) instead of having an actual event handler delegate as a field in your class for each event that your class exposes. That helps reduce the footprint of your class if it contains a lot of events that will not always have a subscriber. (http://msdn.microsoft.com/en-us/library/8843a9ch.aspx) (http://msdn.microsoft.com/en-us/library/system.componentmodel.component.events.aspx)
Dr. Wily's Apprentice
A: 

Look into Ninjects Extension the MessageBroker, and on the index changed raise a published event, and subscribe to the event on the form side.

The messagebroker is rather useful in most cases.

Another thought would be implement an observer pattern and add the form as an observer to the controls event.

Gnostus
+2  A: 

This can be a disadvantage of a UserControl. You have to re-publish the events and the properties of one or more of its embedded controls. Consider the alternative: if this UserControl only contains a ListBox then you are much better off simply inheriting from ListBox instead of UserControl.

Anyhoo, you'll need to re-fire the SelectedIndexChanged event. And surely you'll need to be able to let the client code read the currently selected item. Thus:

public partial class UserControl1 : UserControl {
    public event EventHandler SelectedIndexChanged;

    public UserControl1() {
        InitializeComponent();
    }

    private void listBox1_SelectedIndexChanged(object sender, EventArgs e) {
        EventHandler handler = SelectedIndexChanged;
        if (handler != null) handler(this, e);
    }
    public object SelectedItem {
        get { return listBox1.SelectedItem; }
    }
}
Hans Passant
I find this approach better because it looks like the event is triggered from `this` instead of an "unknown" control somewhere in some other control, which is what happens if you just do `listBox1.SelectedIndexChanged += value` in your user control..
Patrick
Thanks. This worked perfect.
Wildhorn