【问题标题】:ListView and Messagebox weird bug?ListView 和 Messagebox 奇怪的错误?
【发布时间】:2012-08-12 15:50:28
【问题描述】:

我有一个使用 ListView 的项目。用户可以从列表视图中选择一些东西(它在详细信息模式下设置) - 并且在某些情况下会出现一个消息框,要求确认是/否。确认代码不会以任何方式修改 ListView 或选择。代码在 SelectedIndexChanged 事件处理程序中。

问题是这样的——当我做出一个创建弹出窗口的选择时——程序最初按预期工作。当我将鼠标移回列表视图时,它会导致选择更改为鼠标下方的符号(无需单击) - 就好像“HoverSelect”已打开(当它未打开时)。这仅在我做出涉及弹出消息框的选择后才会发生。

觉得我弄坏了一些东西,我决定写一个简单的测试。我创建了一个带有硬编码值的列表视图并输入了以下代码:

 private void listView1_SelectedIndexChanged(object sender, EventArgs e)
      {

            listView1.Enabled = false;
            MessageBox.Show("Test");
            listView1.Enabled = true;

      }

当我进行选择时 - 事件被触发两次。我不确定这是否与我原来的问题有关,或者只是另一个巧合。

添加:在我上面的测试示例中 - 发生以下情况:

第一个选择 - “测试” 第二个选择 - “测试” “测试” 第三... N - “测试” “测试”

所以我认为这是我主要问题的另一个方面。删除代码以禁用/启用列表视图没有任何区别。

如何让 MessageBox 和 ListView 互相“玩得很好”?

【问题讨论】:

  • 在不禁用列表视图的情况下尝试代码。
  • 您正在禁用 SelectedIndexChanged 中的整个列表视图...为什么?我猜当您重新启用它时,列表视图会重新初始化其选择状态,再次引发事件......
  • 在没有禁用列表视图的情况下仍然存在。而且我需要在我的主程序中禁用列表视图代码,因为当用户进行选择时启动的过程需要一些时间。
  • 如果要显示某种形式的模态对话框,则在选择更改时,则不需要禁用并重新启用ListView,因为它们无法与之交互无论如何。
  • 好的,那么肯定是其他原因导致事件被引发,我认为您需要发布更多代码。

标签: c# winforms listview messagebox


【解决方案1】:

ListView.HideSelection 设置为false

ListView.HideSelection:获取或设置一个值,该值指示当控件失去焦点时,控件中的选定项是否保持突出显示。

【讨论】:

  • 没有区别。在主程序中已经是错误的。当我在测试程序中将其更改为 false 时,问题仍然存在。
【解决方案2】:

前几天我遇到了类似的问题,在执行将焦点从ListView 移开的操作时遇到了奇怪的问题。在我的例子中,点击 ListViewItem 更新了 UI 的另一部分,这使得 ListView 失去焦点并且不开心。

我的解决方案是执行以下操作 - 添加以下方法:

private bool AllowToLoseFocus = true;

private void MyListView_Leave(object sender, EventArgs e)
{
   if(!AllowToLoseFocus)
        MyListView.Focus();
}

private void MyListView_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
    AllowToLoseFocus = false;
    //do stuff here
    AllowToLoseFocus = true;
}

也许不是最简洁的解决方案,并且可能不适用于您的情况...但值得一试!

【讨论】:

  • 还是不行。出现 MessageBoxes 时不会触发“MyListView_Leave”代码。仅当我通过单击另一个 winform 元素手动更改焦点时才会发生。
  • 哦,这很烦人。对不起,我帮不上忙!
【解决方案3】:

我想我解决了你的问题:

private void listView1_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
    {
        if (e.IsSelected)
        {
            if (!e.Item.Selected)
            {
                e.Item.Selected = false;
            }
            MessageBox.Show("test");
        }
    }

【讨论】:

  • 解决了测试程序的问题。但是问题仍然存在于主程序上。您的 if (!e.ItemSelected) 部分代码也是多余的。
【解决方案4】:

SelectedIndexChanged 事件触发两次,因为它的行为是设计使然。

当用户选择一个项目而不按 CTRL 来执行一个 多选时,控件先清除上一个选择。 在这种情况下,该事件发生一次 以前选择的项目,新选择的项目一次。

更多信息请查看MSDN

我无法重现您的悬停问题,但您可以尝试仅显示一次消息框(仅在您不使用多选时有效)

private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
    if (listView1.SelectedItems.Count > 0)
    {
        MessageBox.Show("Test");
    }
}

【讨论】:

    【解决方案5】:

    快速尝试并立即复制它,这是一个棘手的问题。我可以向您展示一个解决方案,它不是很好,但它有效。您需要在 MessageBox 上使用第二个表单,然后返回禁用/启用列表视图。

    private void listView1_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (listView1.Enabled)
        {
            listView1.Enabled = false;
            Form2 confirm = new Form2();
            confirm.FormClosed += new FormClosedEventHandler(confirm_FormClosed);
            confirm.Show();
        }
    }
    
    void confirm_FormClosed(object sender, FormClosedEventArgs e)
    {
        listView1.Enabled = true;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-28
      • 1970-01-01
      • 1970-01-01
      • 2021-07-23
      • 2018-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多