Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MouseDown in WinForm ListBox Kills SelectedIndexChanged

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.

like image 658
Mike Malter Avatar asked Dec 12 '25 18:12

Mike Malter


1 Answers

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.

like image 196
Edwin Groenendaal Avatar answered Dec 14 '25 17:12

Edwin Groenendaal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!