このページをはてなブックマークに追加このページを含むはてなブックマーク このページをlivedoor クリップに追加このページを含むlivedoor クリップ

目次

個人的によく使うプロパティ

  • View = Details
    • 1行表示モード。
  • FullRowSelect = True
    • 選択がセル単位ではなく行単位になる。
  • TabStop = False
    • 基本的にListViewは表示用のため。
  • CheckBox
  • MultiSelect
    • 複数選択可能。
  • SmallImageList
    • アイコン表示。
    • ImageListコントロールを追加してから。

ListViewの選択行の反転防止

  1
  2
  3
  4
  5
  6
  7
    Private Sub lvw_SelectedIndexChanged(ByVal sender As System.Object, _
                                                       ByVal e As System.EventArgs) _
                                                       Handles lvwSettingPrinter.SelectedIndexChanged
        If lvw.SelectedIndices.Count > 0 Then
            lvw.Items(lvw.SelectedIndices(0)).Selected = False
        End If
    End Sub

ListViewのチェックボックスをONにしたときだけラベルに文字列を表示させる

 チェックボックス付きのリストボックス(Viewプロパティ:Details、CheckBoxesプロパティ:True)において、表示されているアイテムを選択するパターンとしては主に次が考えられる。

  • アイテム1つだけ選択
  • 行選択
  • チェックボックスをON

 例えば、チェックボックスをONにしたときだけ、同じフォーム内にあるラベルに文字列を表示したいとする。チェックボックスがOFF⇒ONのときだけ文字列に表示され、ON⇒OFFになったときは文字列が表示されないようにする方法のひとつとして、次のサンプルが考えられる。ラベルの表示だけじゃなく、チェックボックスが1つでもONであれば、[OK]ボタンを有効化する処理も含んでいる。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
Public Class Form1
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        '初期化
        ListView1.CheckBoxes = True     'チェックボックス付き
        ListView1.FullRowSelect = True  '行選択
        ListView1.View = View.Details   '表のような表示モード
 
        btnOK.Enabled = False
        btnCancel.Enabled = True
 
        Label1.Text = "権限:"
 
        Label2.Text = ""
        Label2.AutoSize = False
        Label2.BorderStyle = BorderStyle.Fixed3D    'ラベルが凹むので何も表示されていなくても、何かが表示される部分であることを強調できる。
 
        'ListViewにアイテム追加
        With ListView1
            '可視できる列を2つ追加
            .Columns.Add("ユーザID", 100, HorizontalAlignment.Left)
            .Columns.Add("アクセス許可ネットワーク", 200, HorizontalAlignment.Left)
 
            '1行目の追加
            .Items.Add("root", 0)
            .Items(0).SubItems.Add("LAN+インターネット")
            .Items(0).SubItems.Add("管理者権限")        '3列目は不可視だが、チェックボックスをONにしたときにラベルに表示される。
 
            '2行目の追加
            .Items.Add("user", 1)
            .Items(1).SubItems.Add("LAN")
            .Items(1).SubItems.Add("ユーザー権限")
 
            '3行目の追加
            .Items.Add("guest", 2)
            .Items(2).SubItems.Add("制限LAN")
            .Items(2).SubItems.Add("ユーザー権限")
        End With
 
    End Sub
 
    Private Sub ListView1_ItemCheck(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs) Handles ListView1.ItemCheck
        If e.CurrentValue = CheckState.Unchecked And e.NewValue = CheckState.Checked Then
            'チェックボックスをOFFからONにするときに、ラベルに文字列(この例では選択したListViewの行の3列目)を表示する。
            Label2.Text = ListView1.Items(e.Index).SubItems(2).Text
            Exit Sub
        End If
 
        'それ以外のときは、ラベルに何も表示しない。
        Label2.Text = ""
    End Sub
 
    Private Sub ListView1_ItemChecked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ItemCheckedEventArgs) Handles ListView1.ItemChecked
        If ListView1.CheckedItems.Count() >= 1 Then
            'チェックボックスが1つでもONであれば、[OK]ボタンを有効化する。
            btnOK.Enabled = True
        Else
            btnOK.Enabled = False
        End If
    End Sub
 
    Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
        '画面を閉じる。
        Me.Close()
    End Sub
 
    Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
        '例:別フォームを表示する、チェックがONのものを一覧として何かを処理する
 
        'チェックがONのユーザID一覧(このサンプルでは1列目)
        Dim userList() As String = Nothing
 
        If ListView1.CheckedItems.Count <> 0 Then
            Dim checkedLineNum As Integer = ListView1.CheckedItems.Count
            ReDim userList(checkedLineNum - 1)
            Dim i As Integer
            Dim j As Integer = 0
            For i = 0 To ListView1.Items.Count - 1
                If ListView1.Items(i).Checked = True Then
                    userList(j) = ListView1.Items(i).SubItems(0).Text
                    'サブアイテムならば
                    'userList(j) = ListView1.Items(i).SubItems(1).Text
                    j += 1
                End If
            Next
        End If
 
        'チェックがONのユーザ名一覧を入力とする。
        func(userList)
    End Sub
 
    Private Sub func(ByVal userList() As String)
        '何らかの処理
    End Sub
 
End Class

 実行画面は次の通り。

    チェックをOFF⇒ON↓↑チェックをON⇒OFF

2つのListView間でアイテムを移動する

 ListView1,ListView2という2つのリストボックスをフォームに貼り付け、Button1をクリックすることでListView1で選択したアイテムがListView2に移動する(移動元のListView1からはアイテムが消える)。また、Button2をクリックすることでListView2で選択したアイテムがListView1に移動する。

方法1

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
Public Class Form1
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        With ListView1
            .View = View.Details    '詳細表示にする。
            .FullRowSelect = True   '行選択を有効化する。
            .MultiSelect = True     '複数選択を可能にする。
            .Columns.Add("都道府県コード", 100, HorizontalAlignment.Left)   'ヘッダを追加する。
            .Columns.Add("都道府県名", 100, HorizontalAlignment.Left)
        End With
        With ListView2
            .View = View.Details    '詳細表示にする。
            .FullRowSelect = True   '行選択を有効化する。
            .MultiSelect = True     '複数選択を可能にする。
            .Columns.Add("都道府県コード", 100, HorizontalAlignment.Left)   'ヘッダを追加する。
            .Columns.Add("都道府県名", 100, HorizontalAlignment.Left)
        End With
 
        'アイテムを追加する。
        Dim itemName() As String = {"東京", "大阪", "福島", "北海道", "熊本"}
        Dim itemCode() As String = {"001", "002", "003", "004", "005"}
        For i = 0 To UBound(itemCode)
            Dim item As New ListViewItem
            item.Text = itemCode(i)
            item.SubItems.Add(itemName(i))
            ListView1.Items.Add(item)
        Next
    End Sub
 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        moveItem(ListView1, ListView2)
    End Sub
 
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        moveItem(ListView2, ListView1)
    End Sub
 
    Private Sub moveItem(ByVal lvwFrom As ListView, ByVal lvwTo As ListView)
        For Each selectItem As ListViewItem In lvwFrom.SelectedItems
            Dim setItem(1) As String
            setItem(0) = selectItem.SubItems(0).Text
            setItem(1) = selectItem.SubItems(1).Text
            lvwTo.Items.Add(New ListViewItem(setItem))
            lvwFrom.Items.Remove(selectItem)
        Next
        lvwTo.Sorting = SortOrder.Ascending
        lvwTo.Sort()
    End Sub
 
End Class

隠しデータ

 列にはtagプロパティが存在するので、そこに格納するという手がある。

列幅を固定化

 ColumnWidthChangingイベントを追加する。

Private Sub ListView1_ColumnWidthChanging(ByVal sender As System.Object, _
                                          ByVal e As System.Windows.Forms.ColumnWidthChangingEventArgs) _
                                          Handles ListView1.ColumnWidthChanging
        e.NewWidth = Me.ListView1.Columns(e.ColumnIndex).Width
        e.Cancel = True
End Sub

高速化

  • アイテムのAdd中は描画しない。
    • Add前にBeginUpdate()を呼び、Add後にEndUpdate()を呼ぶ。
  • Sortingプロパティをオフにしておいて、すべてAddし終えてからSortingプロパティをオンにする。
    • そうしないとAddされる度にソートされてしまい単純に無駄な処理が増える。
  • ListViewに追加する項目を配列に格納しておき、AddRange()メソッドで設定すると、高速化に繋がる。