如何在选中复选框时选择列表框中的所有项目?

发布于 2024-07-22 21:44:07 字数 98 浏览 6 评论 0原文

单击复选框时,我需要选择列表框中的所有项目。 是否可以使用一行代码选择列表框中的所有项目? 或者我是否必须循环遍历所有项目并将其中每一项的 selected 设置为 true ?

I need to select all items in a ListBox when a CheckBox is clicked. Is it possible to select all items in the ListBox using a single line of code? Or will I have to loop through all items and set selected to true for each one of them?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

梦一生花开无言 2024-07-29 21:44:09

我使用 Mika 的解决方案,但是如果您有数千个项目,这可能会非常慢。 为了大幅提高速度,您可以短暂关闭可见性。 正如您可能怀疑的那样,列表框实际上不会在操作过程中消失,但在我的情况下,选择速度至少快 10 倍。

myListBox.Visible = false;
for (int i = 0; i < myListBox.Items.Count;i++)
{
    myListBox.SetSelected(i, true);
}
myListBox.Visible = true;

I use Mika's solution, however this can be very slow if you have thousands of items. For a massive speed increase you can turn off visibility briefly. The listbox will not actually disappear during the operation as you might suspect, but the selection occurs at least 10x faster in my case.

myListBox.Visible = false;
for (int i = 0; i < myListBox.Items.Count;i++)
{
    myListBox.SetSelected(i, true);
}
myListBox.Visible = true;
毁虫ゝ 2024-07-29 21:44:09

我想你必须在这里循环。 一次选择所有项目是一个非常具体(而且可能很少见)的用例,在这种情况下提供开箱即用的功能根本没有意义。 此外,无论如何,循环都只有两行代码。

I think you have to loop here. Selecting all items at once is a pretty specific (and probably rare) use case where it simply makes no sense to offer that functionality out of the box. Furthermore, the loop will be just two lines of code anyway.

又爬满兰若 2024-07-29 21:44:09

在此构造函数中,您需要启用所需文本框的多选模式 (MultiExtended)。

public Form1()
{
    InitializeComponent();
    listBox1.SelectionMode = SelectionMode.MultiExtended;
    listBox2.SelectionMode = SelectionMode.MultiExtended;
}

之后,使用循环选择所有内容:

private void selectAll_Click(object sender, EventArgs e)
{
    for (int val = 0; val < listBox1.Items.Count; val++)
    {
        listBox1.SetSelected(val, true);
    }
}

我测试了它。 有用。 您还可以使用[CTRL/SHIFT]按钮+左键单击单独选择项目。

Within this Constructor, you need to enable the multi selection mode (MultiExtended) of the desired text box.

public Form1()
{
    InitializeComponent();
    listBox1.SelectionMode = SelectionMode.MultiExtended;
    listBox2.SelectionMode = SelectionMode.MultiExtended;
}

After this, use a loop to select everything:

private void selectAll_Click(object sender, EventArgs e)
{
    for (int val = 0; val < listBox1.Items.Count; val++)
    {
        listBox1.SetSelected(val, true);
    }
}

I tested it. It works. You can also use the [CTRL/SHIFT] button + left click to select the items individually.

情释 2024-07-29 21:44:09

据我所知,使用任何 .NET 方法选择大量项目都比直接进行 PInvoke 调用慢得多,将 LB_SETSEL 消息 (0x185) 传递给控件,​​并用一个标志指示是否要选择 (1) 或取消选择 (0) 以及魔法值 (-1),该值指示更改应应用于所有项目。

  [DllImport("user32.dll", EntryPoint = "SendMessage")]
  internal static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam);

  // Select All
  SendMessage(listBox.Handle, 0x185, (IntPtr)1, (IntPtr)(-1));

  // Unselect All
  SendMessage(listBox.Handle, 0x185, (IntPtr)0, (IntPtr)(-1));

As far as I can tell, using any of the .NET methods to select a large number of items is far slower than making a direct PInvoke call, passing the LB_SETSEL message (0x185) to the control, with a flag indicating whether you want to Select (1) or Unselect (0) as well as the magic value (-1) which indicates that the change should apply to all items.

  [DllImport("user32.dll", EntryPoint = "SendMessage")]
  internal static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam);

  // Select All
  SendMessage(listBox.Handle, 0x185, (IntPtr)1, (IntPtr)(-1));

  // Unselect All
  SendMessage(listBox.Handle, 0x185, (IntPtr)0, (IntPtr)(-1));
蓝眸 2024-07-29 21:44:09

我见过很多(类似的)答案,它们在逻辑上都做同样的事情,我很困惑为什么它们都不适合我。 关键是将列表框的 SelectionMode 设置为 SelectionMode.MultiSimple。 它不适用于 SelectionMode.MultiExtended。 考虑在列表框中选择多个项目,您将选择模式设置为多种模式,并且大多数人都会选择传统的 MultiExtended 样式,这个答案应该有很大帮助。 而且你不是foreach,而是for

你实际上应该这样做:

lb.SelectionMode = SelectionMode.MultiSimple;
for (int i = 0; i < lb.Items.Count; i++)
    lb.SetSelected(i, true);
lb.SelectionMode = //back to what you want

或者

lb.SelectionMode = SelectionMode.MultiSimple;
for (int i = 0; i < lb.Items.Count; i++)
    lb.SelectedIndices.Add(i);
lb.SelectionMode = //back to what you want

I have seen a number of (similar) answers all which does logically the same thing, and I was baffled why yet they all dont work for me. The key is setting listbox's SelectionMode to SelectionMode.MultiSimple. It doesn't work with SelectionMode.MultiExtended. Considering to select multiple items in a listbox, you will have selection mode set to multiple mode, and mostly people go for the conventional MultiExtended style, this answer should help a lot. And ya not a foreach, but for.

You should actually do this:

lb.SelectionMode = SelectionMode.MultiSimple;
for (int i = 0; i < lb.Items.Count; i++)
    lb.SetSelected(i, true);
lb.SelectionMode = //back to what you want

OR

lb.SelectionMode = SelectionMode.MultiSimple;
for (int i = 0; i < lb.Items.Count; i++)
    lb.SelectedIndices.Add(i);
lb.SelectionMode = //back to what you want
墨落画卷 2024-07-29 21:44:09

就我而言,我有超过 10k 个项目,基本循环方法几乎需要一分钟才能完成。 使用 @DiogoNeves 答案并扩展它,我希望能够选择所有 (Ctrl+A) & 复制(Ctrl+C)。 我用两种方式处理了这个问题。 我使用 BeginUpdate() 和 EndUpdate() 来推迟绘制,但我还添加了直接复制全部 (Ctrl+Shift+C),它甚至不需要在复制之前选择项目。

private static void HandleListBoxKeyEvents(object sender, KeyEventArgs e)
{
    var lb = sender as ListBox;
    // if copy
    if (e.Control && e.KeyCode == Keys.C)
    {
        // if shift is also down, copy everything!
        var itemstocopy = e.Shift ? lb.Items.Cast<object>() : lb.SelectedItems.Cast<object>();
        // build clipboard buffer
        var copy_buffer = new StringBuilder();
        foreach (object item in itemstocopy)
            copy_buffer.AppendLine(item?.ToString());
        if (copy_buffer.Length > 0)
            Clipboard.SetText(copy_buffer.ToString());
    }
    // if select all
    else if (e.Control && e.KeyCode == Keys.A)
    {
        lb.BeginUpdate();
        for (var i = 0; i < lb.Items.Count; i++)
            lb.SetSelected(i, true);
        lb.EndUpdate();
    }
}

In my case i had 10k+ items, the basic loop method was taking almost a minute to complete. Using @DiogoNeves answer and extending it i wanted to be able to select all (Ctrl+A) & copy (Ctrl+C). i handled this 2 ways. i used the BeginUpdate() and EndUpdate() to defer drawing but i also added a direct copy all (Ctrl+Shift+C) which doesn't even bother to select the items before copying.

private static void HandleListBoxKeyEvents(object sender, KeyEventArgs e)
{
    var lb = sender as ListBox;
    // if copy
    if (e.Control && e.KeyCode == Keys.C)
    {
        // if shift is also down, copy everything!
        var itemstocopy = e.Shift ? lb.Items.Cast<object>() : lb.SelectedItems.Cast<object>();
        // build clipboard buffer
        var copy_buffer = new StringBuilder();
        foreach (object item in itemstocopy)
            copy_buffer.AppendLine(item?.ToString());
        if (copy_buffer.Length > 0)
            Clipboard.SetText(copy_buffer.ToString());
    }
    // if select all
    else if (e.Control && e.KeyCode == Keys.A)
    {
        lb.BeginUpdate();
        for (var i = 0; i < lb.Items.Count; i++)
            lb.SetSelected(i, true);
        lb.EndUpdate();
    }
}
我不是你的备胎 2024-07-29 21:44:09

如果你有很多(100+)个项目,这绝对不好,但比循环快得多:
选择列表框并模拟 [home] 和 [shift]+[end] 的按键输入

lb.BeginUpdate();
lb.Select();
SendKeys.Send("{Home}");
SendKeys.Send("+{End}");
lb.EndUpdate();

编辑:仅适用于 SelectionMode.MultiExtended 我猜

DoubleEDit:还要注意,这对于随后使用 lb.selecteditems 执行的代码可能太慢,但对于用户单击的[全选]按钮可能很有用。

this is absolutely not nice but much faster than a loop if you have many many (100+) items:
Select the Listbox and simulate key input of [home] and [shift]+[end]

lb.BeginUpdate();
lb.Select();
SendKeys.Send("{Home}");
SendKeys.Send("+{End}");
lb.EndUpdate();

EDIT: works with SelectionMode.MultiExtended only I guess

DoubleEDit: also be aware that this might be too slow for code being performed with lb.selecteditems afterwards, but it may be useful for an [Select All] button that the user will click.

半﹌身腐败 2024-07-29 21:44:09

全选绝对是开箱即用的:

$("#ListBoxID option").prop("selected", true);

Select All is definetly available out of the box:

$("#ListBoxID option").prop("selected", true);
怪异←思 2024-07-29 21:44:09

我知道这个问题是用 .NET 2.0 标记的,但是如果您在 3.5+ 中可以使用 LINQ,您可以执行以下操作:

ASP.NET Web 表单

var selected = listBox.Items.Cast<System.Web.UI.WebControls.ListItem>().All(i => i.Selected = true);

WinForms

var selected = listBox.SelectedItems.Cast<int>().ToArray();

I know this question is tagged with .NET 2.0 but if you have LINQ available to you in 3.5+, you can do the following:

ASP.NET WebForms

var selected = listBox.Items.Cast<System.Web.UI.WebControls.ListItem>().All(i => i.Selected = true);

WinForms

var selected = listBox.SelectedItems.Cast<int>().ToArray();
陌上芳菲 2024-07-29 21:44:09

我将 nawfal 的想法添加到我已有的想法中,这也与“BeginUpdate”有关。 此外,正如用户所期望的那样,视图位置也被保持。 对我来说,这似乎现在解决了所有问题:

public void SelectAll()
{
    bool prevBusy = MouseHelper.IsBusy;
    MouseHelper.IsBusy = true;
    int topIndex = TopIndex;

    // BUG: In 'SelectionMode.MultiExtended' the box gets crazy
    SelectionMode previousMode = this.SelectionMode;
    this.SelectionMode = SelectionMode.MultiSimple;

    this.BeginUpdate();

    for (int i = 0; i < Items.Count; i++)
    {
        SelectedIndices.Add(i);
    }

    this.EndUpdate();
    this.SelectionMode = previousMode;

    TopIndex = topIndex;
    MouseHelper.IsBusy = prevBusy;
}

I added nawfal's idea to what I had already, which was also with 'BeginUpdate'. Additionaly the view position is maintained too, as the user would expect. For me this seems to solve all problems now:

public void SelectAll()
{
    bool prevBusy = MouseHelper.IsBusy;
    MouseHelper.IsBusy = true;
    int topIndex = TopIndex;

    // BUG: In 'SelectionMode.MultiExtended' the box gets crazy
    SelectionMode previousMode = this.SelectionMode;
    this.SelectionMode = SelectionMode.MultiSimple;

    this.BeginUpdate();

    for (int i = 0; i < Items.Count; i++)
    {
        SelectedIndices.Add(i);
    }

    this.EndUpdate();
    this.SelectionMode = previousMode;

    TopIndex = topIndex;
    MouseHelper.IsBusy = prevBusy;
}
<逆流佳人身旁 2024-07-29 21:44:09
private void Button_Click(object sender, RoutedEventArgs e)
    {

            listbox.SelectAll();

    }
private void Button_Click(object sender, RoutedEventArgs e)
    {

            listbox.SelectAll();

    }
所谓喜欢 2024-07-29 21:44:07

事实上,ListBox.Items 是一个普通对象集合,并返回普通的无类型对象,不能进行多选(默认情况下)。

如果您想多选所有项目,那么这将起作用:

   for (int i = 0; i < myListBox.Items.Count;i++)
   {
       myListBox.SetSelected(i, true);
   }

The fact is that ListBox.Items is a plain object collection and returns plain untyped objects, which cannot be multi-selected (by default).

If you want to multi-select all items, then this will work:

   for (int i = 0; i < myListBox.Items.Count;i++)
   {
       myListBox.SetSelected(i, true);
   }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文