3

I'm writing some code to detect toggling of selections in a WindForms ListBox with MultiSelect turned on. Since SelectedIndexChanged only lets me see what is selected after the click, I was looking for a way to detect what was selected before the ListBox was clicked. I implemented the MouseDown event and I can get exactly what I want, but an unfortunate side effect is that I have killed the SelectedIndexChanged event. It will not fire.

Is this known behavior? Are there any thoughts about getting to the selection list before the click?

Thanks.

Edited to include code snippets as requested.

Designer generated events:

this.lbPhysicianClinic.SelectedIndexChanged += new System.EventHandler( this.lbPhysicianClinic_SelectedIndexChanged );
this.lbPhysicianClinic.MouseDown += new System.Windows.Forms.MouseEventHandler( this.lbPhysicianClinic_MouseDown );

Code snippet showing MouseDown event:

private void lbPhysicianClinic_MouseDown( object sender, MouseEventArgs e )
    {
        List<Clinic_List_ByPhysicianResult> Selected = this.PhysicianGetSelectedClinics( this.lbPhysicianClinic.SelectedIndices );
    }

Code snippet showing SelectedIndexChanged event:

private void lbPhysicianClinic_SelectedIndexChanged( object sender, EventArgs e )
    {
        try
        {
            if ( this.FormInitComplete && this.RefreshUIComplete )
            {
                List<Clinic_List_ByPhysicianResult> Selected = this.PhysicianGetSelectedClinics( this.lbPhysicianClinic.SelectedIndices );

                Clinic_List_ByPhysicianResult DroppedClinic = new Clinic_List_ByPhysicianResult();

I set a breakpoint in each event and if the MouseDown event is there, the SelectedIndexChanged event never fires. It only fires when the MouseDown event is gone.

Hopefully this clarifies things.

Mike Malter
  • 1,018
  • 1
  • 14
  • 38
  • You can't kill it with an event. Did you actually override OnMouseDown in a derived class? – Hans Passant May 18 '11 at 20:57
  • No. I added the event through Visual Studio. I set a breakpoint in both events, and only the MouseDown event fires. When I comment out the MouseDown event (and remove it from the designer) only then will the SelectedIndexChanged event fire. – Mike Malter May 18 '11 at 23:16
  • You have to post a code snippet. – Hans Passant May 18 '11 at 23:19

1 Answers1

5

The ListBox changes its selection before it raises the MouseDown or SelectedIndexChanged events.

What you need to do is capture the underlying Win32 message and raise an event yourself. You can subclass ListBox to do this.

class MyListBox : ListBox
{
    private const int WM_LBUTTONDOWN = 0x201;

    public event EventHandler PreSelect;

    protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            case WM_LBUTTONDOWN:
                OnPreSelect();
                break;
        }

        base.WndProc(ref m);
    }

    protected void OnPreSelect()
    {
        if(null!=PreSelect)
            PreSelect(this, new EventArgs());
    }

}

You can use the MyListBox class, and add a handler for the PreSelect event like so:

this.lbPhysicianClinic.PreSelect += 
    new EventHandler(this.lbPhysicianClinic_PreSelect);

Inside the event handler you can access the selected indices before the listbox has changed them.

Edwin Groenendaal
  • 2,304
  • 16
  • 8
  • This is really a great idea. One housekeeping issue. How would I be able to drag and drop this from the toolbox? Thank you very much. – Mike Malter May 19 '11 at 16:45
  • If you create a control like this then it will show up on the toolbox, yes. It will appear with a blue cogwheel icon. You may need to recompile the project for the designer to refresh the toolbox properly. Good luck! – Edwin Groenendaal May 19 '11 at 21:36