根据选择一个列表框中的项目选择/取消选择多个列表框中的项目 - C# Windows 窗体
Posted
技术标签:
【中文标题】根据选择一个列表框中的项目选择/取消选择多个列表框中的项目 - C# Windows 窗体【英文标题】:Select / Deselect Items in multiple listboxes based on selection of an item in one listbox - C# Windows forms 【发布时间】:2021-11-23 04:54:35 【问题描述】:我有一个场景,我有三个列表框。可以在列表框中选择多个项目。 根据一个列表框中的项目选择,我需要在其他列表框中选择和取消选择相应的行。
我有下面的代码,但我遗漏了一些东西。 当我选择和取消选择项目时,它会错误地选择和取消选择其他行项目。
for (int count = 0; count < listBox_1.SelectedIndices.Count; count++)
// Determine if the item is selected.
if (listBox_1.GetSelected(count) == true)
listBox_2.SetSelected(listBox_1.SelectedIndices[count], false);
listBox_3.SetSelected(listBox_1.SelectedIndices[count], false);
else if (listBox_1.GetSelected(count) == false)
// Select all items that are not selected.
listBox_2.SetSelected(listBox_1.SelectedIndices[count], true);
listBox_3.SetSelected(listBox_1.SelectedIndices[count], true);
这里 LB1 中的项目选择应该控制 LB2 和 LB3 中的选择。 现在,由于在 LB1 中选择了第 2 和第 3 项 - 在 LB2 和 LB3 中也应选择第 2 和第 3 项。但事实并非如此。
========================================= 更新
当用户选择 ListBox2 或 ListBox3 中的项目时,我如何复制该行为
private void listBox_1_SelectedIndexChanged_(object sender, EventArgs e)
listBox_2.ClearSelected();
listBox_3.ClearSelected();
int userSelectedIndex = listBox_1.Items.Count;
if (listBox_1.SelectedIndices.Count > 0)
for (int count = 0; count < listBox_1.Items.Count; count++)
// Determine if the item is selected.
if (listBox_1.GetSelected(count) == true)
if (count <= listBox_2.Items.Count)
listBox_2.SetSelected(count, true);
if (count <= listBox_3.Items.Count)
listBox_3.SetSelected(count, true);
else if (listBox_1.GetSelected(count) == false)
// Select all items that are not selected.
if (count <= listBox_2.Items.Count)
listBox_2.SetSelected(count, false);
if (count <= listBox_3.Items.Count)
listBox_3.SetSelected(count, false);
当用户选择 ListBox 2 中的项目时,LB1 和 LB3 中的项目也应该被选中。
private void listBox_2_SelectedIndexChanged(object sender, EventArgs e)
listBox_1.ClearSelected(); // ITS giving error here.
listBox_3.ClearSelected();
int userSelectedIndex = listBox_2.Items.Count;
if (listBox_2.SelectedIndices.Count > 0)
for (int count = 0; count < listBox_2.Items.Count; count++)
// Determine if the item is selected.
if (listBox_2.GetSelected(count) == true)
if (count <= listBox_1.Items.Count)
listBox_1.SetSelected(count, true);
if (count <= listBox_3.Items.Count)
listBox_3.SetSelected(count, true);
else if (listBox_2.GetSelected(count) == false)
// Select all items that are not selected.
if (count <= listBox_1.Items.Count)
listBox_1.SetSelected(count, false);
if (count <= listBox_3.Items.Count)
listBox_3.SetSelected(count, false);
【问题讨论】:
“但我错过了一些东西。” ...不是问题。什么没有按预期工作? @JohnG - 更新 - 它错误地选择和取消选择其他行项目。 好的,我认为这更清楚了。当用户选择/取消选择列表框 1 中的一行时,什么会被认为是“正确的”?什么会被认为是“不正确的”?当另一个列表框中的另一行被选择/取消选择时,我们不知道是什么决定了应该选择/取消选择哪个列表框行。你能举个例子吗? @JohnG - 更新了一个例子。希望这会有所帮助。 或者简单地使用foreach
循环遍历SelectedIndicies
集合。类似...foreach (int selectedIndex in listBox_1.SelectedIndices) ...
...发布的代码在哪里被调用?
【参考方案1】:
不清楚这段代码在哪里被调用。我会简单地清除其他 list2 和 list3 框,然后设置与列表框 1 中相同的选定索引...类似于...
listBox_2.ClearSelected();
listBox_3.ClearSelected();
foreach (int selectedItem in listBox_1.SelectedIndices)
listBox_2.SetSelected(selectedItem, true);
listBox_3.SetSelected(selectedItem, true);
根据 OP 评论进行编辑……
我仍然没有遵循要求,但是,如果您希望所有 ListBoxes
在每个 ListBox
中都具有“相同的选定索引”,那么下面的代码可能会有所帮助。
您当前的解决方案可能遇到的一个问题是可能的循环引用。例如,listBox_1_SelectedIndexChanged
代码中,有一行代码……
listBox_2.SetSelected(count, true);
... 这会在列表框 2 中设置选定的索引,这将触发 listBox_2_SelectedIndexChanged
事件。然后......在那个事件代码中你有代码......
listBox_1.SetSelected(count, true);
...这将“再次”触发列表框 1 事件。
很明显,这可能会创建一个无限循环引用,其中每个事件只是调用另一个事件并且永远不会结束。
鉴于事件中的代码可能需要在另一个ListBoxes
中“设置”一个索引,那么可能需要在代码之前从其SelectedIndexChanged
事件中关闭/取消订阅列表框设置索引,然后在设置索引后开启/重新订阅事件。
因此在下面的解决方案中,由于所有三个ListBoxes
都使用相同的事件,因此代码在代码开始之前关闭/取消订阅每个ListBox
事件,然后打开/重新启动完成后订阅事件。
此外,正如@zaggler 正确指出的那样,检查ListBox
是否确实具有给定值的索引,有必要在设置索引之前检查索引是否在有效范围内,以避免索引超出边界异常。
private void listBox_SelectedIndexChanged(object sender, EventArgs e)
listBox_1.SelectedIndexChanged -= new EventHandler(listBox_SelectedIndexChanged);
listBox_2.SelectedIndexChanged -= new EventHandler(listBox_SelectedIndexChanged);
listBox_3.SelectedIndexChanged -= new EventHandler(listBox_SelectedIndexChanged);
ListBox lb_1 = (ListBox)sender;
ListBox lb_2;
ListBox lb_3;
switch (lb_1.Name)
case "listBox_1":
lb_2 = listBox_2;
lb_3 = listBox_3;
break;
case "listBox_2":
lb_2 = listBox_1;
lb_3 = listBox_3;
break;
default:
lb_2 = listBox_1;
lb_3 = listBox_2;
break;
lb_2.ClearSelected();
lb_3.ClearSelected();
foreach (int selectedItem in lb_1.SelectedIndices)
if (selectedItem < lb_2.Items.Count)
lb_2.SetSelected(selectedItem, true);
if (selectedItem < lb_3.Items.Count)
lb_3.SetSelected(selectedItem, true);
listBox_1.SelectedIndexChanged += new EventHandler(listBox_SelectedIndexChanged);
listBox_2.SelectedIndexChanged += new EventHandler(listBox_SelectedIndexChanged);
listBox_3.SelectedIndexChanged += new EventHandler(listBox_SelectedIndexChanged);
【讨论】:
John - 在 listBox_1_SelectedIndexChanged(object sender, EventArgs e) 处调用代码 那么我发布的代码应该可以工作了。 确实如此。 ClearSelected() 是我所缺少的。谢谢约翰 @JNL 你没有错过ClearSelected
,你的条件倒退了。
@zaggler - 你能帮忙编辑问题吗?当用户选择 ListBox 2/ ListBox 3 中的项目时,如何复制行为【参考方案2】:
这里 LB1 中的项目选择应该控制 LB2 和 LB3 中的选择。现在,由于在 LB1 中选择了第 2 和第 3 项 - 在 LB2 和 LB3 中也应选择第 2 和第 3 项。但事实并非如此。
我建议遍历listBox_1
...的所有项目...
for (int idx = 0; idx <= listBox_1.Items.Count - 1; idx++)
if (listBox_1.GetSelected(idx))
if (idx <= listBox_2.Items.Count)
listBox_2.SetSelected(idx, true);
if (idx <= listBox_3.Items.Count)
listBox_3.SetSelected(idx, true);
else
if (idx <= listBox_2.Items.Count)
listBox_2.SetSelected(idx, false);
if (idx <= listBox_3.Items.Count)
listBox_3.SetSelected(idx, false);
请注意,我也进行了检查以确保索引存在,否则如果索引不存在,它可能会抛出错误。
【讨论】:
感谢您的帮助@zaggler。 @JNL 欢迎,如果使用 JohnG 答案,我会检查索引是否存在,否则会抛出异常。以上是关于根据选择一个列表框中的项目选择/取消选择多个列表框中的项目 - C# Windows 窗体的主要内容,如果未能解决你的问题,请参考以下文章