【PowerShellでGUI 3】ListBox

PowerShellで作成するWindwos Formアプリの部品のうち、今回はリストボックスについてです。

ListBox

今回のサンプルアプリの画面イメージはこちら。

そして上記画面のソースコードがこちら

using namespace System.Windows.Forms
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

[Application]::EnableVisualStyles()

# フォーム
$frame = New-Object Form -Property @{
    Text            = 'Sample App'
    Size            = New-Object Drawing.Size(320, 200)
    MaximizeBox     = $false
    FormBorderStyle = 'FixedDialog'
    Font            = New-Object Drawing.Font('Meiryo UI', 8.5)
}

# ラベル定義
$Label1 = New-Object Label -Property @{
    Text        = 'Sample Application'
    Location    = New-Object Drawing.Point(20, 20)
    AutoSize    = $True
}
$Label2 = New-Object Label -Property @{
    Location    = New-Object Drawing.Point(20, 200)
    AutoSize    = $True
}
$frame.Controls.AddRange(@($Label1,$Label2))
    
# リストボックス定義
$ListBox1 = New-Object ListBox -Property @{
    Location      = New-Object Drawing.Point(20, 50)
    Size          = New-Object Drawing.Size(100, 100)
    SelectionMode = 'MultiExtended'
    Sorted        = $True
}
for ($i = 1; $i -lt 11; $i++) {
    [void]$ListBox1.Items.Add("Item " + $i.ToString('00'))
}
$frame.Controls.Add($ListBox1)

$ListBox2 = New-Object ListBox -Property @{
    Location      = New-Object Drawing.Point(180, 50)
    Size          = New-Object Drawing.Size(100, 100)
    SelectionMode = 'MultiExtended'
    Sorted        = $True
}
$frame.Controls.Add($ListBox2)

# ボタン定義
$Button1 = New-Object Button -Property @{
    Text        = '>>'
    Location    = New-Object Drawing.Point(130, 60)
    Width       = 40
}
$Button1.Add_Click({
    for ($i = 0; $i -lt $ListBox1.SelectedItems.Count; $i++) {
        [void]$ListBox2.Items.Add($ListBox1.SelectedItems.Item($i))
    }
    while ($ListBox1.SelectedIndex -ge 0) {
        [void]$ListBox1.Items.RemoveAt($ListBox1.SelectedIndex)
    }
})
$frame.Controls.Add($Button1)

$frame.ShowDialog()

解説

29~38行目が左側のListBoxの定義、および初期表示内容の定義の部分です。

$ListBox1 = New-Object ListBox -Property @{
    Location      = New-Object Drawing.Point(20, 50)
    Size          = New-Object Drawing.Size(100, 100)
    SelectionMode = 'MultiExtended'
    Sorted        = $True
}
for ($i = 1; $i -lt 11; $i++) {
    [void]$ListBox1.Items.Add("Item " + $i.ToString('00'))
}
$frame.Controls.Add($ListBox1)

プロパティの設定のポイントとしては、次の2つです。

  • SelectionMode に MultipleExtended を設定→Shiftキーを押しながらの範囲選択や、Ctrlキーを押しながらの複数選択ができるようにするモードです。
  • SprtedをTrueに設定することで、項目値で自動的にソートされた状態で表示されるようになります。

その他のプロパティについては、マイクロソフトの公式サイトで確認してみてください。

また、リストへの値の追加は
 Controlos.Add
で行います。[void]の記載はなくてもよいのですが、これがないと実行時に追加先のIndex値が標準出力に出力されてしまうため、これを破棄するために[void]を記載しています。

54~61行目が「>>」のボタンをクリックしたときの定義で、処理の内容としては、左側のListBoxで選択したItemを右側のListBoxに移動させています。

$Button1.Add_Click({
    for ($i = 0; $i -lt $ListBox1.SelectedItems.Count; $i++) {
        [void]$ListBox2.Items.Add($ListBox1.SelectedItems.Item($i))
    }
    while ($ListBox1.SelectedIndex -ge 0) {
        [void]$ListBox1.Items.RemoveAt($ListBox1.SelectedIndex)
    }
})

ポイントとしては、右側のListBoxへの追加処理の都度左側のListBoxから削除してしまうとIndex番号がずれてしまって正しく処理ができなくなってしまうため、まずは選択されている分をすべて右側のListBoxに追加して、そのあとで選択されている項目についての削除処理を実施するという流れにする点です。

今回は短いですがここまで。
次回はコンボボックスついて記載予定です。

以上、参考になれば幸いです。