【PowerShellでGUI 6】DataGridView応用編 リンク表示列 & チェックボックス表示列

前回、PowerShellで作成するWindwos Formアプリの部品データグリッドビューについて書いてみましたが、今回はその応用編で、データグリッドビューの中に
 ・リンクを表示する列
 ・チェックボックスを表示する列
を設定する方法です。

DataGridViewLinkColumn & DataGridViewCheckBoxColumn

今回のサンプルアプリの画面イメージはこちら。
前回作成した簡易なエクスプローラーライクなものをベースにしています。

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

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(650, 600)
    MaximizeBox     = $false
    FormBorderStyle = 'FixedDialog'
    Font            = New-Object Drawing.Font('Meiryo UI', 8.5)
}

# 表示対象フォルダー設定用テキストボックス
$tbxFolder = New-Object TextBox -Property @{
    Location      = New-Object Drawing.Point(20, 20)
    Width         = 400
    ReadOnly      = $True
}
$frame.Controls.Add($tbxFolder)

# フォルダー選択ダイアログ表示ボタン
$btnRef = New-Object Button -Property @{
    Location      = New-Object Drawing.Point(425, 20)
    Text          = '...'
    Width         = 30
}
$frame.Controls.Add($btnRef)

# 上位階層に移動するボタン
$btnUp = New-Object Button -Property @{
    Location      = New-Object Drawing.Point(460, 20)
    Text          = 'Up'
    Width         = 30
    Enabled       = $false
}
$frame.Controls.Add($btnUp)

$fbdRef = New-Object FolderBrowserDialog -Property @{
    ShowNewFolderButton = $false
}

# データグリッドビュー
$DataGridV = New-Object DataGridView -Property @{
    Location        = New-Object Drawing.Point(20, 50)
    Size            = New-Object Drawing.Size(600, 500)
    AutoSizeColumnsMode = "AllCells"
    ReadOnly            = $True
    AllowUserToAddRows  = $false
    RowHeadersVisible   = $false
    MultiSelect         = $false
    SelectionMode       = 'FullRowSelect'
}

# 名前列(リンク)
$colName = New-Object DataGridViewLinkColumn -Property @{
    Name = "FileName"
    HeaderText = '名前'
}
[void]$DataGridV.Columns.Add($colName)

# 各列の情報設定
[void]$DataGridV.Columns.Add('UpdateTime','更新日時')
$DataGridV.Columns[1].DefaultCellStyle.Format = 'yyyy/MM/dd HH:mm:ss'
[void]$DataGridV.Columns.Add('IsContainer','IsContainer')
$DataGridV.Columns[2].Visible = $false
[void]$DataGridV.Columns.Add('Size','サイズ')
$DataGridV.Columns[2].DefaultCellStyle.Format = '#,##0 KB'
$DataGridV.Columns[3].DefaultCellStyle.Alignment = 'MiddleRight'

$cbcReadOnly = New-Object DataGridViewCheckBoxColumn -Property @{
    Name = 'ReadOnly'
    HeaderText = "読取専用"
}
[void]$DataGridV.Columns.Add($cbcReadOnly)

# DataGridViewに値を設定する処理
$scrbSetGrid = {
    $DataGridV.Rows.Clear()
    $files = (Get-ChildItem $tbxFolder.Text)
    foreach ($fi in $files){
        if (!$fi.PSIsContainer){
            switch ($fi.Length) {
                {$_ -lt 1024} { $size = 1  }
                Default {$size = ($_ / 1024)}
            }
            $blRO = $fi.IsReadOnly
        } else {
            $size = $null
            $blRO = $false
        }
        $DataGridV.Rows.Add($fi.Name, $fi.LastWriteTime, $fi.PSIsContainer, $size, $blRO)
    }
    $btnUp.Enabled = !([string]::IsNullOrEmpty((Split-Path $tbxFolder.Text -Parent)))
}

$btnRef.Add_Click({
    if ($fbdRef.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK){
        $tbxFolder.Text = $fbdRef.SelectedPath
        . $scrbSetGrid
    }
})

$btnUp.Add_Click({
    $tbxFolder.Text = (Split-Path $tbxFolder.Text -Parent)
    . $scrbSetGrid
})

# リンククリック時の処理
$DataGridV.Add_CellContentClick({
    $ClickRowIndex = $_.RowIndex
    if ($_.ColumnIndex -eq 0) {
        if ($DataGridV.Rows[$ClickRowIndex].Cells[2].Value -eq 'True'){
            $tbxFolder.Text = (Join-Path $tbxFolder.Text $DataGridV.Rows[$ClickRowIndex].Cells[0].Value)
            . $scrbSetGrid
        } else {
            Start-Process -FilePath (Join-Path $tbxFolder.Text $DataGridV.Rows[$ClickRowIndex].Cells[0].Value)
        }
    }
})

$frame.Controls.Add($DataGridV)

$frame.ShowDialog()

解説

58~62行目がリンクを表示する列の定義をしている部分になります。
列のオブジェクトをDataGridViewLinkColumnクラスとして定義し、定義したオブジェクトをデータグリッドビューに追加するという流れになります。

$colName = New-Object DataGridViewLinkColumn -Property @{
    Name = "FileName"
    HeaderText = '名前'
}

112~122行目がリンクがクリックされたときの処理を記載している部分です。
イベントとしては、通常のクリックのイベントで、その中でクリックされた列がリンクの列だった場合に処理を行うように記載するかたちになります。

$DataGridV.Add_CellContentClick({
    $ClickRowIndex = $_.RowIndex
    if ($_.ColumnIndex -eq 0) {
        if ($DataGridV.Rows[$ClickRowIndex].Cells[2].Value -eq 'True'){
            $tbxFolder.Text = (Join-Path $tbxFolder.Text $DataGridV.Rows[$ClickRowIndex].Cells[0].Value)
            . $scrbSetGrid
        } else {
            Start-Process -FilePath (Join-Path $tbxFolder.Text $DataGridV.Rows[$ClickRowIndex].Cells[0].Value)
        }
    }
})

最後に、73~77行目がチェックボックスを表示する列の定義をしている部分で、DataGridViewCheckBoxColumnクラスを使用して定義します。

$cbcReadOnly = New-Object DataGridViewCheckBoxColumn -Property @{
    Name = 'ReadOnly'
    HeaderText = "読取専用"
}
[void]$DataGridV.Columns.Add($cbcReadOnly)

今回はここまで。
次回は引き続きデータグリッドビューの応用編として、画像を表示するパターンを記載予定です。

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