I'm writing a simple demo of using drag and drop in VB.NET using a ListBox
and a PictureBox. The ListBox contains a list of filenames of various bitmaps.
The user can drag and drop a file from the ListBox to the PictureBox and
the PictureBox will display the image. Sounds simple, right? The problem
is that somehow the DoDragDrop method of the ListBox seems to be preventing
the user from changing the items in the ListBox. Visually, the ListBox looks
as if the user changed items, but none of the ListBox's properties reflect
the change. The funny thing is that it works the first time. It's when
the user tries to do a second drag and drop that the problem starts occurring.
I'm posting the exact sample code at the end of this e-mail so you can run
the problem yourself.

My question is two-fold:
- What am I doing wrong?
- What can I do to fix this?

A short sample app is at the end of this post. Remember to perform the drag
and drop operation more than once. It works the first time, but not after
that. Also, if you comment out the DoDragDrop line in the ListBox1_MouseDown
event procedure, the selected item changes every time. So it appears the
problem has something to do with calling the DoDragDrop method from within
the MouseDown event. Thanks.

- Jim

Option Strict On

Public Class Form1
Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents ListBox1 As System.Windows.Forms.ListBox
Friend WithEvents PictureBox1 As System.Windows.Forms.PictureBox
Friend WithEvents btnExit As System.Windows.Forms.Button
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.ListBox1 = New System.Windows.Forms.ListBox()
Me.PictureBox1 = New System.Windows.Forms.PictureBox()
Me.btnExit = New System.Windows.Forms.Button()
Me.SuspendLayout()
'
'ListBox1
'
Me.ListBox1.Location = New System.Drawing.Point(16, 16)
Me.ListBox1.Name = "ListBox1"
Me.ListBox1.Size = New System.Drawing.Size(184, 225)
Me.ListBox1.Sorted = True
Me.ListBox1.TabIndex = 0
'
'PictureBox1
'
Me.PictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D
Me.PictureBox1.Location = New System.Drawing.Point(216, 16)
Me.PictureBox1.Name = "PictureBox1"
Me.PictureBox1.Size = New System.Drawing.Size(256, 224)
Me.PictureBox1.TabIndex = 1
Me.PictureBox1.TabStop = False
'
'btnExit
'
Me.btnExit.DialogResult = System.Windows.Forms.DialogResult.Cancel
Me.btnExit.Location = New System.Drawing.Point(400, 248)
Me.btnExit.Name = "btnExit"
Me.btnExit.TabIndex = 2
Me.btnExit.Text = "E&xit"
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.CancelButton = Me.btnExit
Me.ClientSize = New System.Drawing.Size(490, 279)
Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.btnExit,
Me.PictureBox1, Me.ListBox1})
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.Name = "Form1"
Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
Me.Text = "Form1"
Me.ResumeLayout(False)

End Sub

#End Region

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles MyBase.Load
FillListBox()
PictureBox1.AllowDrop = True
End Sub

Private Sub ListBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
Handles ListBox1.MouseDown
If e.Button = MouseButtons.Left Then
If ListBox1.SelectedIndex > -1 Then
ListBox1.DoDragDrop(ListBox1.SelectedItem.ToString, DragDropEffects.Copy)
Debug.WriteLine("MouseDown - " & ListBox1.SelectedItem.ToString)
End If
End If
End Sub

Private Sub ListBox1_SelectedIndexChanged(ByVal sender As Object, ByVal
e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
Debug.WriteLine("SelectedIndexChanged - " & ListBox1.SelectedItem.ToString)
End Sub

Private Sub PictureBox1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs)
Handles PictureBox1.DragEnter
If e.Data.GetDataPresent(GetType(System.String)) = True Then
e.Effect = DragDropEffects.Copy
End If
End Sub

Private Sub PictureBox1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs)
Handles PictureBox1.DragDrop
If Not PictureBox1.Image Is Nothing Then
PictureBox1.Image.Dispose()
PictureBox1.Image = Nothing
End If
PictureBox1.Image = Image.FromFile(CStr(e.Data.GetData(GetType(System.String))))
End Sub

Private Sub btnExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles btnExit.Click
Me.Close()
End Sub

Private Sub FillListBox()
'Fill list box with list of bitmap files in the Windows directory
ListBox1.DataSource = System.IO.Directory.GetFiles("C:\WinNT\", "*.bmp")
End Sub
End Class