【问题标题】:Select / Deselect Multiple items in multiple listboxes选择/取消选择多个列表框中的多个项目
【发布时间】:2021-11-26 15:58:13
【问题描述】:

我正在尝试在多个列表框中实现多个项目选择。这可能吗?

要求:

  1. 当用户选择 ListBox1 中的项目时 - 应选择 ListBox2 和 ListBox3 中的项目。
  2. 当用户取消选择 ListBox1 中的项目时 - 应取消选择 ListBox2 和 ListBox2 中的项目。 我能够在 LB1 上实现这一目标。

对于 ListBox2 和 ListBox3,应该重复相同的行为 1 和 2。 我在这里遇到了困难。

我有下面的代码 - 但它当然会遇到 stackoverflow 异常。我错过了什么?

 private void listBox_1_SelectedIndexChanged_(object sender, EventArgs e)
 {

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


private void listBox_2_SelectedIndexChanged(object sender, EventArgs e)
{           
    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);
            }
        }
   }
}

【问题讨论】:

  • 嗨,您收到堆栈溢出异常的原因是,当您将所选索引从一个列表框更新到另一个列表框时,您会不断地循环调用相同的事件处理程序,为防止这种情况,您可以添加类似以下内容的字段:_isUpdating 并在事件处理程序内部,检查您当前是否正在更新,如果是,则从事件返回,如果不是,则处理事件,然后您可以设置 @ 987654325@ 到 true,然后再对其他列表框进行任何更改,并在完成后将其设置为 false
  • 我注意到虽然您使用的是ItemsCountuserSelectedIndex,但它们始终是相同的,然后什么也不做,然后循环遍历每个索引以检查是否它被选中 &lt;= 另一个列表框项目计数,在这种情况下始终为真,因为您的 listboxes 中有相同数量的 items
  • 在您的问题中,您能否更具体地说明您的要求?正如您所说:"When user selects an item in ListBox1 - items in ListBox2 and ListBox3 should be selected." 这是基于索引还是其他条件?如果是基于索引的,请检查我提供的答案,避免堆栈溢出异常,并根据索引选择其他列表框中的项目
  • 不要使用三个 ListBox,而是使用一个 DataGridView。

标签: c# winforms listbox listboxitem


【解决方案1】:

此字段用于避免堆栈溢出异常。

private bool _isUpdating;

我也在使用SelectedValueChanged 事件而不是SelectedIndexChanged,但它仍然可以工作,这里有 3 个不同的复选框(这可以通过重构它如何处理要更新的列表框来改进)

private void listBox1_SelectedValueChanged(object sender, EventArgs e)
{
    if (this._isUpdating)
    {
        //// Prevent Stack Overflow by exiting out
        return;
    }

    var selectedIndexes = this.listBox1.SelectedIndices;
    this._isUpdating = true;

    this.listBox2.SelectedItems.Clear();
    this.listBox3.SelectedItems.Clear();

    foreach (int index in selectedIndexes)
    {
        //// Listbox2
        var foundItem = this.listBox2.Items[index];
        this.listBox2.SelectedItems.Add(foundItem);

        //// Listbox3
        var foundItem2 = this.listBox3.Items[index];
        this.listBox3.SelectedItems.Add(foundItem2);
    }

    this._isUpdating = false;
}

private void listBox2_SelectedValueChanged(object sender, EventArgs e)
{
    if (this._isUpdating)
    {
        //// Prevent Stack Overflow by exiting out
        return;
    }

    var selectedIndexes = this.listBox2.SelectedIndices;
    this._isUpdating = true;

    this.listBox1.SelectedItems.Clear();
    this.listBox3.SelectedItems.Clear();

    foreach (int index in selectedIndexes)
    {
        //// Listbox1
        var foundItem = this.listBox1.Items[index];
        this.listBox1.SelectedItems.Add(foundItem);

        //// Listbox3
        var foundItem2 = this.listBox3.Items[index];
        this.listBox3.SelectedItems.Add(foundItem2);
    }

    this._isUpdating = false;
}

private void listBox3_SelectedValueChanged(object sender, EventArgs e)
{
    if (this._isUpdating)
    {
        //// Prevent Stack Overflow by exiting out
        return;
    }

    var selectedIndexes = this.listBox3.SelectedIndices;
    this._isUpdating = true;

    this.listBox1.SelectedItems.Clear();
    this.listBox2.SelectedItems.Clear();

    foreach (int index in selectedIndexes)
    {
        //// Listbox1
        var foundItem = this.listBox1.Items[index];
        this.listBox1.SelectedItems.Add(foundItem);

        //// Listbox2
        var foundItem2 = this.listBox2.Items[index];
        this.listBox2.SelectedItems.Add(foundItem2);
    }

    this._isUpdating = false;
}

如前所述,避免了Stack Overflow Exception,并确保在给定index 处选择/取消选择Listbox 中的项目也会选择另一个listboxes index 中的项目。

【讨论】:

    猜你喜欢
    • 2021-11-23
    • 2017-01-04
    • 1970-01-01
    • 2014-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    相关资源
    最近更新 更多