web-dev-qa-db-ja.com

ListBoxすべてのアイテムを選択

CheckBoxをクリックしたときに、ListBoxのすべての項目を選択する必要があります。 1行のコードを使用して、ListBoxのすべての項目を選択することは可能ですか?それとも、すべてのアイテムをループして、それぞれのアイテムを選択してtrueに設定する必要がありますか?

ありがとう:)

25
Rashmi Pandit

ここでループする必要があると思います。一度にすべてのアイテムを選択することは、非常に具体的な(そしておそらくまれな)ユースケースであり、そのままの機能を提供することは単に意味がありません。さらに、ループはとにかく2行のコードになります。

5
Joey

実際はListBox.Itemsは単純なオブジェクトコレクションであり、型なしの単純なオブジェクトを返します。複数のオブジェクトを選択することはできません(デフォルト)。

すべてのアイテムを複数選択する場合、これは機能します。

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

私の知る限り、.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));
8
EricLaw

私は論理的に同じことをする多くの(類似した)答えをすべて見てきましたが、なぜそれらすべてが私にとってうまくいかないのか困惑しました。重要なのは、リストボックスのSelectionModeSelectionMode.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

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
8
nawfal

私はミカのソリューションを使用しますが、何千ものアイテムがある場合、これは非常に遅くなる可能性があります。大幅な速度向上のために、一時的に表示をオフにすることができます。疑わしいかもしれませんが、操作中にリストボックスは実際には消えませんが、私の場合、選択は少なくとも10倍速く行われます。

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

このコンストラクター内で、目的のテキストボックスの複数選択モード(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]ボタン+左クリックを使用して、アイテムを個別に選択することもできます。

1

私はこの質問に.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();
1
fujiiface

すべて選択はすぐに使用できます。

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

これは絶対にナイスではありませんが、多くの(100以上の)アイテムがある場合、ループよりはるかに高速です。リストボックスを選択し、[home]と[shift] + [end]のキー入力をシミュレートします。

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

編集:SelectionMode.MultiExtendedでのみ機能します

DoubleEDit:これは、後でlb.selecteditemsを使用して実行されるコードには遅すぎる可能性があることにも注意してください。ただし、ユーザーがクリックする[すべて選択]ボタンには役立ちます。

0
doomi

私の場合、10,000個以上のアイテムがあったので、基本的なループ方法は完了するまでに1分近くかかっていました。 @DiogoNeves回答を使用してそれを拡張すると、すべてを選択(Ctrl + A)およびコピー(Ctrl + C)できるようになりました。私はこれを2つの方法で処理しました。 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();
    }
}
0
Justin

すでに持っていたものに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;
}