six demon bag

Wind, fire, all that kind of thing!

2015-03-09

Drag & Drop in a PowerShell GUI

For a little PowerShell GUI (using Windows Forms) the requirement to drag & drop files into a listbox came up. Some quick googling showed several articles (like this one) suggesting to set AllowDrop = $true and add a handler for the DragEnter event.


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

$form = New-Object Windows.Forms.Form

$handler = {
  $_.Data.GetFileDropList() | % {
    $listbox.Items.Add($_)
  }
}

$listbox = New-Object Windows.Forms.ListBox
$listbox.AllowDrop = $true
$listbox.Add_DragEnter($handler)

$form.Controls.Add($listbox)
$form.ShowDialog()

However, with these settings the items were already added when dragging them over the listbox. What I actually wanted was a drop handler to add the items after releasing the mouse button.

I tried replacing $listbox.Add_DragEnter($handler) with $listbox.Add_DragDrop($handler), but that didn't do anything at all. After some further research I came across this answer to a similar question on StackOverflow, which pushed me into the right direction.

Apparently proper drag & drop requires 2 handlers, a DragEnter handler setting the DragDropEffect, and the actual DragDrop handler for handling the dropped items:

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

$form = New-Object Windows.Forms.Form

$handler = {
  $_.Data.GetFileDropList() | % {
    $listbox.Items.Add($_)
  }
}

$listbox = New-Object Windows.Forms.ListBox
$listbox.AllowDrop = $true
$listbox.Add_DragEnter({$_.Effect = [Windows.Forms.DragDropEffects]::Copy})
$listbox.Add_DragDrop($handler)

$form.Controls.Add($listbox)
$form.ShowDialog()

Posted 19:18 [permalink]