andreat
andreat

Reputation: 347

Listview SelectedIndexChanged with MessageBox fires ItemDrag

I have a ListView with SelectedIndexChanged and ItemDrag event handlers. If I open up a MessageBox in SelectedIndexChanged, it fires ItemDrag.

The problem is easily reproduced by creating a list with some element and putting a MessageBox in SelectedIndexChanged and a breakpoint in the ItemDrag method.

private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{        
        MessageBox.Show("Selected Index Changed");
}

private void listView1_ItemDrag(object sender, ItemDragEventArgs e)
{
}

Any suggestions on why this is happening?

Upvotes: 0

Views: 202

Answers (1)

Hans Passant
Hans Passant

Reputation: 941317

I see it. The notification comes straight from Windows, .NET is not involved. These kind of MessageBox induced problems are not uncommon, it causes re-entrancy problems that are very similar to the misery caused by the infamous DoEvents() method. ListView just wasn't written to assume that its SelectedIndexChanged event does something this drastic.

I think the underlying trigger are the focus changes, it regains focus after closing the message box with very good odds that the mouse was moved in the mean time. Which looks like an attempted drag as well. Note how you don't get the event when you use the keyboard to close the message box.

There is a Universal Solution to these kind of re-entrancy problems, works to solve this one as well. The approach is to delay the display of the dialog, waiting until the event was dispatched and handled by the control and code inside ListView is no longer active. Could be done with a Timer, but the most elegant way is by using the BeginInvoke() method:

    private void listView1_SelectedIndexChanged(object sender, EventArgs e) {
        this.BeginInvoke(new Action(() => MessageBox.Show("Okay now")));
    }

Upvotes: 2

Related Questions