ListBox も VB6.0 の時からお世話になっているコントロールです。
今回は、自分が普段あんまりやらない使い方(オーナードロー・複数列・FormatString)
を主にやってみました。
■参考文献
ListBox クラス
■実行画像
オーナードロー
複数列・FormatString
Public Class ListBoxTest
Private m_tabControl As TabControl
Private Sub ListBoxTest_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.m_tabControl = New TabControl()
Me.m_tabControl.Dock = DockStyle.Fill
Me.m_tabControl.TabPages.Clear()
Me.Controls.Add(Me.m_tabControl)
' オーナードロー
Dim ownerDrawPage As TabPage = New TabPage("OwnerDraw")
Me.m_tabControl.TabPages.Add(ownerDrawPage)
Dim ownerDrawListBox As ListBox = New ListBox()
ownerDrawPage.Controls.Add(ownerDrawListBox)
With ownerDrawListBox
' オーナードローにする
.DrawMode = DrawMode.OwnerDrawFixed
' スクロールバーを常に表示
.ScrollAlwaysVisible = True
.Dock = DockStyle.Fill
.BeginUpdate()
With .Items
.Clear()
.Add(Color.Tomato)
.Add(Color.LimeGreen)
.Add(Color.LightSeaGreen)
.Add(Color.MediumPurple)
.Add(Color.LimeGreen)
.Add(Color.LightSeaGreen)
.Add(Color.MediumPurple)
.Add(Color.Tomato)
End With
.EndUpdate()
AddHandler .DrawItem, AddressOf OwnerDrawItem
End With
' 複数行
Dim mulitColumnPage As TabPage = New TabPage("MulitColumn")
Me.m_tabControl.TabPages.Add(mulitColumnPage)
Dim multiColumnListBox As ListBox = New ListBox()
mulitColumnPage.Controls.Add(multiColumnListBox)
Dim dt As DataTable = New DataTable("test")
dt.Columns.Add("id", GetType(Integer))
dt.Columns.Add("ひづけ", GetType(DateTime))
For counter As Integer = 0 To 20
System.Threading.Thread.Sleep(100)
dt.Rows.Add(counter + 100, DateTime.Now)
Next
With multiColumnListBox
.Dock = DockStyle.Fill
.MultiColumn = True
' 複数選択できるようにする
.SelectionMode = SelectionMode.MultiExtended ' Control キーなどを押しながら選択
'.SelectionMode = SelectionMode.MultiSimple ' Control キーなどを押す必要なし
' 書式指定
.FormattingEnabled = True
.FormatString = " yy/MM/dd HH:mm:ss:ms "
' データバインド
.DataSource = dt.DefaultView
.DisplayMember = "ひづけ"
.ValueMember = "id"
.ColumnWidth = CInt(.CreateGraphics().MeasureString(.Items(.Items.Count - 1).ToString(), .Font).Width)
End With
' ContextMenuStrip
Dim context As ContextMenuStrip = New ContextMenuStrip()
Me.ContextMenuStrip = context
'' 選択されている情報
Dim selectedMenu As ToolStripMenuItem = New ToolStripMenuItem("選択されてる情報")
context.Items.Add(selectedMenu)
AddHandler selectedMenu.Click, AddressOf SelectedOut
End Sub
' ListBox.Item を オーナードローする
Private Sub OwnerDrawItem(ByVal sender As Object, ByVal e As DrawItemEventArgs)
Dim lstBox As ListBox = DirectCast(sender, ListBox)
Dim itm As Color = DirectCast(lstBox.Items(e.Index), Color)
Dim rect As Rectangle = New Rectangle(e.Bounds.X + 1, _
e.Bounds.Y + 1, _
lstBox.GetItemRectangle(e.Index).Width, _
lstBox.GetItemRectangle(e.Index).Height - 1)
'' 背景
If e.Index Mod 2 = 0 Then
e.Graphics.FillRectangle(System.Drawing.SystemBrushes.Window, rect)
Else
' 偶数行のみ LinearGradientBrush で塗りつぶし
Using brush As System.Drawing.Drawing2D.LinearGradientBrush _
= New System.Drawing.Drawing2D.LinearGradientBrush(rect, Color.White, itm, 0.0F)
e.Graphics.FillRectangle(brush, rect)
End Using
End If
'' 文字
Using textBrush As System.Drawing.SolidBrush = New System.Drawing.SolidBrush(itm)
e.Graphics.DrawString(itm.Name, _
e.Font, _
textBrush, _
New Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))
End Using
'' フォーカスがある時の枠を描画する
e.DrawFocusRectangle()
End Sub
' 選択されている情報 を 出力ウィンドウに出力
Private Sub SelectedOut(ByVal sender As Object, ByVal e As System.EventArgs)
If Me.m_tabControl.SelectedTab Is Nothing Then Return
Dim tp As TabPage = Me.m_tabControl.SelectedTab
Dim lbox As ListBox = DirectCast(tp.Controls(0), ListBox)
Dim SelectedIndices As ListBox.SelectedIndexCollection = _
lbox.SelectedIndices
Dim selectedItems As ListBox.SelectedObjectCollection = _
lbox.SelectedItems()
Console.WriteLine("ActiveTab:" & tp.Text)
Console.WriteLine("全項目数:" & lbox.Items.Count())
Console.WriteLine("選択項目数:" & SelectedIndices.Count())
Console.WriteLine("SelectedValue:")
Console.WriteLine(Convert.ToString(lbox.SelectedValue))
Console.WriteLine("SelectedIndices:")
For Each index As Integer In SelectedIndices
Console.WriteLine(index.ToString())
Next
Console.WriteLine("SelectedItems:")
For Each item As Object In selectedItems
If TypeOf (item) Is DataRowView Then
Dim dr As DataRowView = DirectCast(item, DataRowView)
For Each col As DataColumn In dr.DataView.Table.Columns
Console.Write(" " & col.ColumnName & "→" & Convert.ToString(dr(col.ColumnName)))
Next
Console.WriteLine()
Else
Console.WriteLine(Convert.ToString(item))
End If
Next
End Sub
End Class