-
Problem with Drag and Drop
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
-
Re: Problem with Drag and Drop
Oh, one other thing. If you run the sample app on Windows XP, change the
path in the FillListBox subroutine to point to "C:\Windows\" (or whatever
directory you have some BMP files in). Thanks.
- Jim
-
Re: Problem with Drag and Drop
The Problem lies in the SelectedItem property. Actually if you do the mouse
down the item is not already selected. You have to use the SelectedIndex
and get then the the according item. Please find the code below which is
working.
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.Items.Item(ListBox1.SelectedIndex).ToString,
DragDropEffects.Copy)
End If
End If
End Sub
-
Re: Problem with Drag and Drop
Hi Andreas,
Thanks, that works just fine. But I can't help but wonder if this is a bug
in .NET. I can't imagine any situation where you would want the SelectedItem
and the SelectedIndex to be out of sync with each other.
- Jim
"Andreas" <andreas_munich@hotmail.com> wrote:
>
>The Problem lies in the SelectedItem property. Actually if you do the mouse
>down the item is not already selected. You have to use the SelectedIndex
>and get then the the according item. Please find the code below which is
>working.
>
>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.Items.Item(ListBox1.SelectedIndex).ToString,
>DragDropEffects.Copy)
> End If
> End If
> End Sub
-
Re: Problem with Drag and Drop
Jim,
the problem is related to the DoDragDrop. If you delete that line, the SelectedItem
is equal to the SelectedIndex.
If you keep the DoDragDrop method, and print the text of the selected item
then it is always the old one. If you delete that line, then the correct
information is displayed.
Perhaps a professional VB.NET programmer can find out why that happens.
Best regards
Andreas
-
I'm glad I found this. I have spent ages wondering why this doesn't work but just put it down to me not understanding the new language. I would like to know though if it's a bug in the framework or wherever it might be or if I'm just doing something wrong. The same fault happens with the old FileListBox as well, which I first started using but gave up on!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Development Centers
-- Android Development Center
-- Cloud Development Project Center
-- HTML5 Development Center
-- Windows Mobile Development Center
|