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

发布于 2024-11-14 06:07:36 字数 1815 浏览 2 评论 0原文

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

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

实际发生的情况是处理程序方法被调用两次(实际上 ListView 应该在选择更改时触发两个事件,一个用于取消选择,另一个用于新选择的项目,但我有一个 e.IsSelected< /code> 开头的语句仅捕获选定的项目,因此实际上您可以说触发了四个事件)。

问题是,如果我通过鼠标单击 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;
}

Here is the problem: I have a Windows Forms application that I'm developing, and in one segment I'm using a ListView control.

What I'm trying can be simply stated as: on event ListViewItemSelectionChange show a MessageBox for user to confirm the change, if not confirmed change to let's say the first item. This change to the first item would again fire ListViewItemSelecionChange, so I unregister and re-register the event handler method, so everything should be good, right?

What actually happens is that the handler method is called twice (actually ListView should fire two events on Selection change, one for deselect, other for newly selected item, but I have an e.IsSelected statement at the beginning to catch only selected items, so actually you could say that there are four events fired).

The problem is, if I generated the first event with mouse click on ListView item, and I've unsubscribed before programatically changing to the first item, what generates the second event firing? Is it some focus change because of the MessageBox call? Is there any way to prevent the second event to fire?

I have a simple example solution here, it can't be more simlified (25 SLOC), so if you can, please take a look. Note that commenting the line "if (ShowMessageBox())" stops the second event from firing, is this some focus change problem?

http://www.filedropper.com/listviewtestwithmsgbox

Edit: the relevant code:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小霸王臭丫头 2024-11-21 06:07:36

嗯,你能描述一下选择是如何改变的吗?如果是通过用户单击来选择项目,可能会捕获 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   ";
    }
}

编辑以包含相关代码。

Hmm, can you describe how the selection is being changed to begin with? If it's by the user clicking to select an item, perhaps catch the Click or DoubleClick event rather than the ItemSelectionChanged event? I have this snippet I'm using on a program currently. If the user double clicks the list box (listView, in your case), do something with the selected item.

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   ";
    }
}

Edited to include relevant code.

旧人九事 2024-11-21 06:07:36

实现此目的的一种方法是设置一个标志,指示更改代码是否应该运行。

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

One way to do this is to have a flag which says should the on change code run.

In your ListViewItemSelecionChange code you check the value of the flag and run code accordingly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文