1.ListBox コントロールに関するワンポイントテクニック集(19_Lst_01) (旧、SampleNo.100〜102) |
1 .ListBox の項目のリストに項目を追加する 2 .ListBox の指定行を選択状態にする 3 .ListBox の選択されている項目を取得する 4 .指定行の項目を取得する / 指定行の項目を書き換える 5 .指定行を削除する / 選択されている項目を削除する 6 .ListBox 内のすべての項目を選択する / すべての項目の選択を解除する 7 .選択されている項目数を取得する 8 .項目を高速に書き込む(処理中の再描画を抑制する) 9 .クリック毎に昇順・降順に並べ替える 10.複数選択されている項目を高速に削除する 11.複数選択されている項目を取得する(取得後、テキストボックス等に表示) 12.リストボックスに水平スクロールバーを表示 13.DataSource プロパティ及び AddRange メソッドで配列データを高速に登録 14.ListBox の項目をすべて削除 15.複数選択されているインデックス番号を取得する 16.ListBox の項目を文字列型の配列に確保する 17. 18. 19. 20. ListBox で 65500 件を超えるようなデータを表示する場合、[XP Visual スタイルを有効にする(X)]のチェックボックスを外しておいて下さい。 ListBox で 65500 件を超えるようなデータを表示すると垂直スクロールバーをドラッグで移動させた場合正常に動作しなくなります。 |
下記プログラムコードに関する補足・注意事項 動作確認:Windows 8.1 (Windows 7) / VB2013 (VB2010) / Framework 4.5.1 / 対象の CPU:x86 Option :[Compare Text] [Explicit On] [Infer On] [Strict On] Imports :Imports System.Runtime.InteropServices 参照設定:追加なし その他 : : このサンプル等の内容を無断で転載、掲載、配布する事はお断りします。(私の修正・改訂・削除等が及ばなくなるので) 必要ならリンクをはるようにして下さい。(引用の場合は引用元のリンクを明記して下さい) |
1.ListBox の項目のリストに項目を追加する(100) |
起動時に項目を登録しておくような場合 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click '01.ListBox の項目のリストに項目を追加する ListBox1.Items.Clear() With ListBox1 .Items.Add("あいうえお") .Items.Add("かきくけこ") .Items.Add("さしすせそ") .Items.Add("たちつてと") .Items.Add("なにぬねの") .Items.Add("はひふへほ") .Items.Add("まみむめも") .Items.Add("や ゆ よ") .Items.Add("らりるれろ") .Items.Add("わをん") End With 'リストの項目をリストの最後に追加書き込みする場合 ListBox1.Items.Add("リストの最後に項目を追加しました。") '指定行にリストの項目を追加するような場合(5行目に挿入する) ListBox1.Items.Insert(4, "5行目に挿入しました。") End Sub |
2.ListBox の指定行を選択状態にする(100) |
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click '02.ListBox の指定行を選択状態にする ListBox1.SetSelected(5, True) '0 から初まるので6行目になります。 End Sub |
3.ListBox の選択されている項目を取得する(100) |
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click '03.ListBox の選択されている項目を取得する With ListBox1 If .SelectedIndex <> -1 Then Dim si As String = .SelectedItem.ToString() MessageBox.Show(si & " Index=" & .SelectedIndex) Debug.WriteLine(si & " Index=" & .SelectedIndex) '結果 はひふへほ Index=5 End If End With End Sub |
4.指定行の項目を取得する / 指定行の項目を書き換える(100) |
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click '04.指定行の項目を取得する / 指定行の項目を書き換える '指定行のデータを取得する MessageBox.Show(ListBox1.Items(5).ToString) Debug.WriteLine(ListBox1.Items(5)) '結果 はひふへほ '指定行の項目を書き換える ListBox1.Items(5) = "6行目を書換えました。" End Sub |
5.指定行を削除する / 選択されている項目を削除する(101) |
Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click '05.指定行を削除する / 選択されている項目を削除する MessageBox.Show("4行目と選択されている行を削除します。") '指定の行を削除する(4行目を削除します) ListBox1.Items.RemoveAt(3) '選択されている項目を削除する ListBox1.Items.Remove(ListBox1.SelectedItem) End Sub |
6.ListBox 内のすべての項目を選択する / すべての項目の選択を解除する(101) |
Imports System.Runtime.InteropServices <DllImport("USER32.DLL", CharSet:=CharSet.Auto)> _ Private Shared Function SendMessage( _ ByVal hWnd As IntPtr, _ ByVal wMsg As Integer, _ ByVal wParam As Integer, _ ByVal lParam As Integer) As Integer End Function '複数選択リストボックスの指定の項目を選択(P828) Private Const LB_SETSEL As Integer = &H185 Private frg6 As Boolean Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click '06.ListBox 内のすべての項目を選択する / すべての項目の選択を解除する ListBox1.SelectionMode = SelectionMode.MultiSimple frg6 = Not frg6 'すべての項目を選択状態にする Dim Ret As Integer If frg6 Then Ret = SendMessage(ListBox1.Handle, LB_SETSEL, 1, -1) Else Ret = SendMessage(ListBox1.Handle, LB_SETSEL, 0, -1) End If 'すべての項目を選択状態に設定(データ件数が少ない場合はこちらが簡単) 'ListBox1.BeginUpdate() 'コントロールを再描画しないようにする。 'Dim i As Integer 'For i = 0 To ListBox1.Items.Count - 1 ' ListBox1.SetSelected(i, True) 'Next 'ListBox1.EndUpdate() 'コントロールの描画を再開する。 End Sub ListBox.ClearSelected メソッド があるのなら、すべての項目を選択するメソッドがあってもいいように思うのだが、見当たらないようなので Win32 API 関数を使って操作してみました。 テスト結果は、下記のようになっております。(ListBox への表示データ件数は、200,000 件でテストしております。) Win32 API を使ってのすべて選択 0.016 秒 ListBox1.SetSelected(i, True) でのすべて選択 917秒(約15分) Win32 API を使ってのすべての選択解除 0.016 秒 ListBox1.ClearSelected()でのすべての選択解除 0.4 秒 |
7.選択されている項目数を取得する(101) |
Private Sub Button7_Click(sender As Object, e As EventArgs) Handles Button7.Click '07.選択されている項目数を取得する ListBox1.SelectionMode = SelectionMode.MultiSimple Debug.WriteLine(ListBox1.SelectedItems.Count) MessageBox.Show(String.Format("選択されている項目数 = {0} 項目です。", ListBox1.SelectedItems.Count)) End Sub |
8.項目を高速に書き込む(処理中の再描画を抑制する)(101) |
Private Sub Button8_Click(sender As Object, e As EventArgs) Handles Button8.Click '08.項目を高速に書き込む(処理中の再描画を抑制する) '処理中コントロールの再描画を抑制 Dim sTime As DateTime Dim eTime As DateTime '------------------------------------------------------------------ 'なにもしない場合 ListBox1.Items.Clear() sTime = Now For i As Integer = 0 To 100000 ListBox1.Items.Add(CStr(i).PadLeft(4, CChar(" ")) & " 番目のデータです") Next i eTime = Now MessageBox.Show(eTime.Subtract(sTime).TotalSeconds & " 秒かかりました。") '結果 18.0 秒 '------------------------------------------------------------------------------ ListBox1.Items.Clear() sTime = Now ListBox1.BeginUpdate() 'コントロールを再描画しないようにする。 For i As Integer = 0 To 100000 ListBox1.Items.Add(CStr(i).PadLeft(4, CChar(" ")) & " 番目のデータです") Next i ListBox1.EndUpdate() 'コントロールの描画を再開する。 eTime = Now MessageBox.Show(eTime.Subtract(sTime).TotalSeconds & " 秒かかりました。") '結果 0.8 秒 '------------------------------------------------------------------------------ ListBox1.Items.Clear() sTime = Now ListBox1.Visible = False '一旦非表示(VB6.0 の時のように) For i As Integer = 0 To 100000 ListBox1.Items.Add(CStr(i).PadLeft(4, CChar(" ")) & " 番目のデータです") Next i ListBox1.Visible = True '表示 eTime = Now MessageBox.Show(eTime.Subtract(sTime).TotalSeconds & " 秒かかりました。") '結果 3.7 秒 '------------------------------------------------------------------------------ End Sub |
9.クリック毎に昇順・降順に並べ替える(101) |
Private Sub Button9_Click(sender As Object, e As EventArgs) Handles Button9.Click '09.クリック毎に昇順・降順に並べ替える '------------------------------------------------------------------------------ '対象のデータの準備 ListBox1.SelectionMode = SelectionMode.MultiSimple If ListBox1.Items.Count <> 10000 Then ListBox1.Items.Clear() ListBox1.BeginUpdate() 'コントロールを再描画しないようにする。 For i As Integer = 0 To 9999 ListBox1.Items.Add(CStr(i).PadLeft(4, CChar(" ")) & " 番目のデータです") Next i ListBox1.EndUpdate() 'コントロールの描画を再開する。 End If '------------------------------------------------------------------------------ 'クリック毎に昇順・降順に並べ替える部分 ListBox1.BeginUpdate() ArrayList.Adapter(ListBox1.Items).Reverse() ListBox1.Sorted = True ListBox1.EndUpdate() End Sub |
10.複数選択されている項目を高速に削除する(101) |
Private Sub Button10_Click(sender As Object, e As EventArgs) Handles Button10.Click '10.複数選択されている項目を高速に削除する ListBox1.SelectionMode = SelectionMode.MultiSimple '複数選択されている項目を削除(総当りしないので高速に処理できます) For i As Integer = ListBox1.SelectedIndices.Count - 1 To 0 Step -1 ListBox1.Items.RemoveAt(ListBox1.SelectedIndices(i)) Next End Sub |
11.複数選択されている項目を取得する(テキストボックス等に表示)(102) |
Private Sub Button11_Click(sender As Object, e As EventArgs) Handles Button11.Click '11.複数選択されている項目を取得する(取得後、テキストボックス等に表示) ListBox1.SelectionMode = SelectionMode.MultiSimple 'リストボックスで複数選択されている項目を取得 If ListBox1.SelectedItems.Count - 1 >= 0 Then Dim i As Integer Dim sb As New System.Text.StringBuilder(1000) '選択されている項目を取得 For i = 0 To ListBox1.SelectedItems.Count - 1 'その文字列を連結 sb.Append(ListBox1.SelectedItems(i).ToString() & vbCrLf) Next '取得結果をテキストボックス等に表示する場合 Debug.WriteLine(sb.ToString()) End If End Sub |
12.リストボックスに水平スクロールバーを表示(102) |
Private Sub Button12_Click(sender As Object, e As EventArgs) Handles Button12.Click '12.リストボックスに水平スクロールバーを表示 ListBox1.Items.Add("あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやいゆえよらりるれろ") If ListBox1.HorizontalScrollbar Then '水平スクロールバーを非表示に ListBox1.HorizontalScrollbar = False Else 'リストボックスに水平スクロールバーを表示 ListBox1.HorizontalScrollbar = True End If End Sub |
13.DataSource プロパティ及び AddRange メソッドで配列データを高速に登録(102) |
配列データは下記のようにでも設定して事前に用意しておいて下さい。 Dim ss(9999) As String Private Sub Button13_Click(sender As Object, e As EventArgs) Handles Button13.Click '13.DataSource プロパティ及び AddRange メソッドで配列データを高速に登録 Dim sTime As DateTime Dim eTime As DateTime For i As Integer = 0 To 9999 ss(i) = CStr(i).PadLeft(4, CChar(" ")) & " 番目のデータです" Next i sTime = Now '配列データを高速に登録 'DataSource プロパティを設定した場合、 'ユーザーは項目のコレクションを変更できません。 ListBox1.DataSource = ss eTime = Now MessageBox.Show(eTime.Subtract(sTime).TotalSeconds & " 秒かかりました。") ListBox1.DataSource = Nothing ListBox1.Refresh() MessageBox.Show("") sTime = Now '配列データを高速に追加登録 Try ListBox1.Items.AddRange(ss) Catch ex As Exception MessageBox.Show(ex.Message) ListBox1.DataSource = Nothing End Try eTime = Now MessageBox.Show(eTime.Subtract(sTime).TotalSeconds & " 秒かかりました。") End Sub どちらも瞬時に書き込みできます。 |
14.ListBox の項目をすべて削除(102) |
Private Sub Button14_Click(sender As Object, e As EventArgs) Handles Button14.Click '14.ListBox の項目をすべて削除 '項目をすべて削除 Try ListBox1.Items.Clear() Catch ex As Exception MessageBox.Show(ex.Message) ListBox1.DataSource = Nothing End Try End Sub |
15.複数選択されているインデックス番号を取得する(102) |
Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click '15.複数選択されているインデックス番号を取得する For i As Integer = 0 To ListBox1.SelectedIndices.Count - 1 Debug.WriteLine(ListBox1.SelectedIndices(i)) Next End Sub |
16.ListBox の項目を文字列型の配列に確保する(102) |
Private Sub Button16_Click(sender As Object, e As EventArgs) Handles Button16.Click '16.ListBox の項目を文字列型の配列に確保する '項目を文字列型の配列に確保する Dim ListBoxItems() As String = DirectCast(ArrayList.Adapter(ListBox1.Items).ToArray(GetType(String)), String()) '配列に確保したデータを表示 For n As Integer = 0 To ListBoxItems.GetUpperBound(0) Debug.WriteLine(ListBoxItems(n)) Next End Sub |
17. |
18. |
19. |
20. |
検索キーワード及びサンプルコードの別名(機能名) |
リストの項目を追加する(リストの最後の追加書込みする) リストの項目を追加する(5行目に挿入する) 指定行を選択状態にする 選択されている項目を取得する(その1) 選択されている項目を取得する(その2) 指定行の項目を取得する/指定行の項目を書き換える すべての項目を選択状態にする すべての項目の選択状態を解除する 指定行を削除する 選択されている項目を削除する 選択されている項目数を取得する 項目を高速に書き込む(処理中の再描画を抑制する) クリック毎に昇順・降順に並べ替える 複数選択されている項目を高速に削除する 複数選択されている項目を取得する(テキストボックス等に表示) リストボックスに水平スクロールバーを表示 DataSourceで配列データを高速に登録 AddRangeメソッドで配列データを追加登録 項目をすべて削除 複数選択されているインデックス番号を取得する ランダムな配列データを作成する |