2016-03-04

PowerShellでユーザーフォームを作る - ドラッグ&ドロップの実装 -

PowerShellでは、ユーザーの好みに合わせて、独自にフォームを作成することができます。

今回は「PowerShellでユーザーフォームを作る - ドラッグ&ドロップの実装 -」です。

不特定多数の人が使うようなフォームを作成する場合、一番に考慮しなければいけないのはその操作性で、「誰でも簡単に使える」ようなものにする必要があります。

そんな時に欠かせない機能のひとつが「ドラッグアンドドロップ」です!

データを取得するときに、「ファイル選択ダイアログを開いて…フォルダの階層を辿って…このファイルと、このファイルと、このファイルと・・・」なんて作業をする必要が無くなります!

<今回の完成品>

ドロップしたところ

前置きはこの辺にして、早速スクリプトを記述していきます。

# ドラッグ&ドロップの実装

Add-Type -AssemblyName System.Windows.Forms

$form = New-Object System.Windows.Forms.Form
$form.Size = "300,300"
$form.StartPosition = "CenterScreen"
$form.Text = "タイトル"

# リストボックスの生成
$Listbox =  New-Object System.Windows.Forms.ListBox
$Listbox.Location = "10,10"
$Listbox.Size = "260,200"
$Listbox.AllowDrop = $True

# ドラッグエンター イベント
$Enter = {
  $_.Effect = "All"
}
$Listbox.Add_DragEnter($Enter)

# ドラッグドロップ イベント
$Drop = {
    $Name = @($_.Data.GetData("FileDrop"))

    # 1つずつ取得し、リストボックスに追加
    For ( $i = 0 ; $i -lt $Name.Count ; $i++ )
    {
        [void]$Listbox.Items.Add($Name[$i])
    }
}
$Listbox.Add_DragDrop($Drop)

# 閉じるボタン
$Button = New-Object System.Windows.Forms.Button
$Button.Location = "200,220"
$Button.size = "80,30"
$Button.text  = "閉じる"
$Button.DialogResult = [System.Windows.Forms.DialogResult]::Cancel

$form.Controls.AddRange(@($Listbox,$Button))

$Form.Showdialog()

上記内容をコピーし、PowerShell ISEに貼り付けて、実行すると空のリストボックスが表示されます。
そこに適当なファイル・フォルダをドラッグ&ドロップすると、そのデータのパスが表示されます。

それでは解説をしていきます。
また過去の記事で解説した部分については割愛致します。

内容をご確認いただきたい場合は【ユーザーフォーム - 基礎編 -】をご覧ください。

*****解説*****************************************************************************

ドラッグ&ドロップを実装するには以下の手順が必要となります。
 手順1 対象コントロールのAllowDropプロパティをTrueにする
 手順2 ドラッグエンターイベントを設定する
 手順3 ドラッグドロップイベントを設定する 

この手順を念頭に置いた上で、サンプルスクリプトを見てみましょう。

$Listbox.AllowDrop = $True
ここで、上記の手順1を実施し、リストボックスへのドラッグ&ドロップを許可しています。
例えば、サンプルスクリプトには他にボタンが設置されていますが、この処理をしていないため、ボタンにデータをドラッグ&ドロップしても何も起こりません。

# ドラッグエンター イベント
$Enter = {
    $_.Effect = "All"
}
$Listbox.Add_DragEnter($Enter)
次に、リストボックスに対してドラッグエンターイベントを設定しています。(上記手順2)
これは、「データがドラッグされた状態でリストボックス上に入ってきた時」に発生します。
DragEventArgsクラスのEffectプロパティは「ドラッグされているデータに対して、どのような操作を行うか」を指定します。
今回は「All」としていますが他の選択肢として「Copy」や「Move」があります。
詳細はDragDropEffects 列挙体を参照ください。

ドラッグエンターイベントがどのタイミングで発生しているのかイマイチわからないという場合は、「$_.Effect = "All"」の部分を「write-host "このタイミングです!!"」に書き換えて、何かしらのデータをドラッグした状態でリストボックス上を行ったり来たりさせてみてください。

# ドラッグドロップ イベント
$Drop = {
    $Name = @($_.Data.GetData("FileDrop"))

    # 1つずつ取得し、リストボックスに追加
    For ( $i = 0 ; $i -lt $Name.Count ; $i++ )
    {
        [void]$Listbox.Items.Add($Name[$i])
    }
}
$Listbox.Add_DragDrop($Drop)
次に、リストボックスに対してドラッグドロップイベントを設定しています。(上記手順3)
これは、「リストボックス上でデータがドロップされた時」に発生します。
まず、DragEventArgsクラスのData.GetDataプロパティでドロップされたデータのパスを配列として取得しています。
その後、For文を用いてリストボックスに追加しています。

*************************************************************************************************

解説は以上となります。

条件付けによっては対象のデータを絞る(テキストファイルだけ許可する、テキストファイル以外は許可する)ことも可能です。

ドラッグ&ドロップが使えるのと使えないのとでは、その操作性に大きな差が生まれます。
特にデータを取り込む処理を行う場合などは、対象データの指定が格段に楽になりますので、ぜひとも実装して欲しい機能です。

=============================================================
本投稿に関する疑問や質問には可能な限りお答えさせていただきます。
お気軽にコメントやメールをお送りください。
(リクエストも歓迎します)
メール:tkk-powershell@gmail.com
また、間違いのご指摘・アドバイス等も歓迎いたします。
=============================================================
Google+、Twitterで更新情報をお届けしています!
ぜひフォローをお願い致します!           
=============================================================
スポンサーリンク


1 件のコメント:

  1. ListBoxではなくtextboxで実装してみたいのですが、どのようにすればよいでしょうか?

    返信削除

疑問・質問・リクエスト お気軽にどうぞ (^O^)/