使用MessageBoxes的ListView ItemChanged拼图 - ItemSelectionChanged被调用两次

时间:2011-06-08 15:30:37

标签: c# winforms listview focus messagebox

问题在于:我正在开发一个Windows窗体应用程序,在一个段中我使用的是ListView控件。

我正在尝试的内容可以简单地说明:在事件ListViewItemSelectionChange上显示MessageBox以便用户确认更改,如果未确认则更改为让我们说第一项。对第一项的这一更改将再次触发ListViewItemSelecionChange,因此我取消注册并重新注册事件处理程序方法,所以一切都应该是好的,对吗?

实际发生的是处理程序方法被调用两次(实际上ListView应该在选择更改时触发两个事件,一个用于取消选择,另一个用于新选择的项目,但我有一个e.IsSelected语句一开始只捕获选定的项目,所以实际上你可以说有四个事件被解雇了。

问题是,如果我通过鼠标单击ListView项目生成第一个事件,并且我在以编程方式更改为第一个项目之前取消订阅,那么生成第二个事件的是什么?由于MessageBox调用,它是否有一些焦点变化?有没有办法阻止第二次事件发生?

我这里有一个简单的示例解决方案,它不能更加简化(25 SLOC),所以如果可以,请看一下。注意,注释“if(ShowMessageBox())”行会阻止第二个事件触发,这是一个焦点变化问题吗?

http://www.filedropper.com/listviewtestwithmsgbox

编辑:相关代码:

private void listViewWithSelection1_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
    // listview actually generates two ItemSelectionChanged events,
    // one for deselect of a item, and another event for a newly selected item (which we want here).
    if (e.IsSelected)
    {
        if (ShowMessageBox())
            Button1_Click(null, EventArgs.Empty);

        label1.Text += "item selected   ";
    }
}

private bool ShowMessageBox()
{
    return MessageBox.Show("Change to first item instead?", "test", MessageBoxButtons.YesNo) == DialogResult.Yes;
}

private void Button1_Click(object sender, EventArgs e)
{
    // change ti first ListView item
    listView1.ItemSelectionChanged -= listViewWithSelection1_ItemSelectionChanged;
    listView1.Items[0].Selected = true;
    listView1.ItemSelectionChanged += listViewWithSelection1_ItemSelectionChanged;
}

2 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是使用一个标志,表示更改代码应该运行。

在ListViewItemSelecionChange代码中,检查标志的值并相应地运行代码。

答案 1 :(得分:1)

嗯,你能描述一下如何改变选择吗?如果是用户点击选择项目,可能会捕获Click或DoubleClick事件而不是ItemSelectionChanged事件?我现在正在使用这个程序片段。如果用户双击列表框(在您的情况下为listView),请对所选项目执行某些操作。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private bool ShowMessageBox()
    {
        return MessageBox.Show("Change to first item instead?", "test", MessageBoxButtons.YesNo) == DialogResult.Yes;
    }

    private void listView1_Click(object sender, EventArgs e)
    {
        if (ShowMessageBox())
            listView1.TopItem.Selected = true;
            label1.Text += "item selected   ";
    }
}

编辑包含相关代码。