我遇到了非常奇怪的WinForms行为,这似乎是一个框架错误。
情况:
在空表格上,将2 ListView
放在一起。在控件没有焦点时禁用HideSelection
以使选择可见。 View
属性(详细信息,大图标)似乎并不重要,但我发现详细信息使点击更容易(在这种情况下,添加一列)。
是否启用MultiSelect
也无关紧要。
(不涉及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]);
}
}
该错误有时会发生在以下场景中(如果我非常快速地执行这些步骤,我只能重现(例如,总体上不到一秒)):
更普遍(这是我的猜想):
我还可以使用此事件处理程序观察右侧列表中的无效选择更改,但我无法从断点中获得任何用途 - 对我来说似乎没有任何可疑之处。在错误的情况下,调用堆栈只包含框架内部方法(当然最顶层的框架除外,它是事件处理程序),因此伪造选择更改来自框架本身。
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
答案 0 :(得分:0)
事实证明你必须设置&#34;重点项目&#34;同样,通过ListViewItem.Focused
或ListView.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错误,这是一个可能或可能不起作用的解决方法。