МышьDown в WinForm ListBox убивает SelectedIndexChanged - PullRequest
3 голосов
/ 18 мая 2011

Я пишу некоторый код для обнаружения переключения выбора в ListBox WindForms с включенным MultiSelect. Так как SelectedIndexChanged позволяет мне видеть только то, что выбрано после щелчка, я искал способ определить, что было выбрано до нажатия ListBox. Я реализовал событие MouseDown, и я могу получить именно то, что хочу, но неприятным побочным эффектом является то, что я убил событие SelectedIndexChanged. Это не будет стрелять.

Это известное поведение? Есть какие-нибудь мысли по поводу попадания в список выбора до нажатия?

Спасибо.

Отредактировано для включения фрагментов кода по запросу.

События, сгенерированные дизайнером:

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

Фрагмент кода, показывающий событие MouseDown:

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

Фрагмент кода, показывающий событие SelectedIndexChanged:

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();

Я устанавливаю точку останова в каждом событии, и если событие MouseDown существует, событие SelectedIndexChanged никогда не срабатывает. Он срабатывает только при исчезновении события MouseDown.

Надеюсь, это прояснит ситуацию.

1 Ответ

5 голосов
/ 19 мая 2011

ListBox меняет свой выбор, прежде чем вызывает события MouseDown или SelectedIndexChanged.

Что вам нужно сделать, так это перехватить сообщение Win32 и инициировать событие самостоятельно. Для этого вы можете создать подкласс ListBox.

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());
    }

}

Вы можете использовать класс MyListBox и добавить обработчик для события PreSelect следующим образом:

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

Внутри обработчика событий вы можете получить доступ к выбранным индексам до того, как список их изменит.

...