Select / 根据在一个列表框中选择一个项目取消选择多个列表框中的项目 - C# Windows 形式

Select / Deselect Items in multiple listboxes based on selection of an item in one listbox - C# Windows forms

我有一个场景,我有三个列表框。列表框中可以 select 编辑多个项目。 基于一个列表框中的 selection 项目,我需要 select 和 deselect 其他列表框中的相应行。

我有下面的代码,但我遗漏了一些东西。 当我 select 和 deselecting 项目时,它 selects 和 deselects 其他行项目不正确。

            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 中的 selection。 现在,由于项目 2 和 3 在 LB1 中 selected - 项目 2 和 3 也应该在 LB2 和 LB3 中 selected。但事实并非如此。

======================================== 更新

当用户select使用 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);
                }
            }
       }
    }

当用户 select 列表框 2 中的项目时,LB1 和 LB3 中的项目也应 selected。

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

Here Selection of items in LB1 should control the selection in LB2 and LB3. Now, since Item 2 and 3 are selected in LB1 - items 2 and 3 should be selected in LB2 and LB3 as well. But that's not what's happening.

我建议循环遍历 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);
                }
            }

请注意,我也进行了检查以确保索引存在,否则如果索引不存在可能会引发错误。

不清楚调用此代码的位置。我会简单地清除其他 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 中“设置”索引,那么可能需要 turn-off/unsubscribe 列表框 [=19] =] 代码设置索引之前的事件,然后 turn-on/re-subscribe 到设置索引之后的事件。

因此在下面的解决方案中,由于同一事件用于所有三个 ListBoxes,代码开始之前来自每个 ListBox 事件的代码 turns-off/un-subscribes,然后 turns-on/re-subscribes 完成后的事件。

此外,正如@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);
}