从代码

时间:2017-10-28 09:05:01

标签: c# winforms listview

我遇到了非常奇怪的WinForms行为,这似乎是一个框架错误。

情况:

在空表格上,将2 ListView放在一起。在控件没有焦点时禁用HideSelection以使选择可见。 View属性(详细信息,大图标)似乎并不重要,但我发现详细信息使点击更容易(在这种情况下,添加一列)。

是否启用MultiSelect也无关紧要。

image

(不涉及button1)

在表单构造函数中,将一些项放入列表中:

this.listView1.Items.Add("item1-1");
this.listView1.Items.Add("item1-2");
this.listView1.Items.Add("item1-3");

this.listView2.Items.Add("item2-1");
this.listView2.Items.Add("item2-2");

现在,当用户选择listView1中的内容时,我们希望在listView2中选择具有相同列表索引的项目。例如。用户在左侧列表视图中选择item1-1,我们要在右侧列表视图中选择item2-1,依此类推。

private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
    // (*1)
    this.listView2.SelectedIndices.Clear();

    if (this.listView1.SelectedIndices.Count != 0 && this.listView1.SelectedIndices[0] < this.listView2.Items.Count)
    {
        // (*1) can also be put here; it makes no difference with regards to the bug (it makes a functional difference though)
        this.listView2.SelectedIndices.Add(this.listView1.SelectedIndices[0]);
    }
}

该错误有时会发生在以下场景中(如果我非常快速地执行这些步骤,我只能重现(例如,总体上不到一秒)):

  • 点击左侧列表中的第1项(开始计数为1)
  • 自动选择右侧列表中的项目1
  • 点击右侧列表中的第1项
  • 点击左侧列表中的第2项
  • 自动选择右侧列表中的项目2
  • 点击右侧列表中的第2项
  • 点击左侧列表中的第1项
  • 自动选择右侧列表中的项目1
  • 等一会儿(约300毫秒)
  • 自动选择右侧列表中的项目2(不正确!)

更普遍(这是我的猜想):

  • 点击左侧列表中的项目
  • 点击右侧列表中刚刚自动选择的项目
  • 快速选择左侧列表中的不同项目
  • 在短时间内自动选择正确的项目
  • 选择会在短暂延迟后跳回上一个项目

我还可以使用此事件处理程序观察右侧列表中的无效选择更改,但我无法从断点中获得任何用途 - 对我来说似乎没有任何可疑之处。在错误的情况下,调用堆栈只包含框架内部方法(当然最顶层的框架除外,它是事件处理程序),因此伪造选择更改来自框架本身。

private void listView2_SelectedIndexChanged(object sender, EventArgs e)
{
    if (this.listView1.SelectedIndices.Count == 0 || this.listView2.SelectedIndices.Count == 0)
    {
        return;
    }

    if (this.listView2.SelectedIndices[0] != this.listView1.SelectedIndices[0])
    {
        // Unless the user MANUALLY selects a DIFFERENT item in the right list view, this should never happen, but it does!
        int j = 5; // BREAKPOINT HERE
    }
}

这个错误并不总是发生,而且似乎对时间敏感,但经过一些&#34;练习&#34;我现在可以在50%的时间内重现它。

我的猜测是,那里有一些非常愚蠢的故障保护机制。当用户点击某个项目时,WinForms会决定稍后检查该项目是否真的被选中,如果未选中该项目,它会再次选择它(即使选择在此期间以编程方式更改) 。但仅此一点是不可能的,因为除非您在选择自动更改后立即明确单击自动选择的项目,否则不会发生错误。

任何人都可以重现这一点,我该如何解决这个问题?

在Win 10 x64上发生这种情况,.NET框架4.5.2和4.7

1 个答案:

答案 0 :(得分:0)

事实证明你必须设置&#34;重点项目&#34;同样,通过ListViewItem.FocusedListView.FocusedItem,例如:

this.listView2.SelectedIndices.Clear();

if (this.listView1.SelectedIndices.Count != 0 && this.listView1.SelectedIndices[0] < this.listView2.Items.Count)
{
   var item_we_want_to_select = this.listView2.Items[this.listView1.SelectedIndices[0]];
   item_we_want_to_select.Selected = true;
   item_we_want_to_select.Focused = true;
}

然而,所有这些听起来都很可疑,我不会再使用ListView这样的GUI。我不能轻易地告诉(或引用文档)关于完全的任何内容,它是否是正确的方法,以及它是否有任何意想不到的副作用。在我看来,似乎原始观察是一个Windows错误,这是一个可能或可能不起作用的解决方法。

相关问题