Drag and drop between ListBoxes

W

wannabe geek

I have a Form with two ListBoxes on either side of a SplitContainer control.
Each ListBox has a number of strings in it. I need to be able to move
strings between the two at will. However, the built in drag and drop
functionality seems very, very, limited (ie, nothing more than functionally
useless cursor changes and additional events that would be easily attainable
without built in dragging and dropping). I am having issues with removing the
old data from the original ListBox.
I tried

{source ListBox}.Remove({data that was dragged});

in the DragDrop event but it only works sometimes. ??
Does anybody have tips? If you need my code just ask. Using VCE 2008.
 
P

Peter Duniho

wannabe said:
I have a Form with two ListBoxes on either side of a SplitContainer control.
Each ListBox has a number of strings in it. I need to be able to move
strings between the two at will. However, the built in drag and drop
functionality seems very, very, limited (ie, nothing more than functionally
useless cursor changes and additional events that would be easily attainable
without built in dragging and dropping). I am having issues with removing the
old data from the original ListBox.
I tried

{source ListBox}.Remove({data that was dragged});

in the DragDrop event but it only works sometimes. ??
Does anybody have tips? If you need my code just ask. Using VCE 2008.

It's true that the drag-and-drop support in the Forms namespace is
minimal. It's up to each application developer to customize the basic
drag-and-drop events to implement exactly the behavior they want.

But, that should not be too much of a problem. As far as the only
problem you've described, if it works sometimes, that should be proof
enough that .NET can work the way you want. You just need to figure out
why the code you've written only works "sometimes".

Nothing more specific than that can be offered unless you post a more
specific question. If you post a concise-but-complete code example,
that may allow someone to explain what's wrong.

Pete
 
W

wannabe geek

What I have here produces unexpected results.
I have two ListBoxes both of their events are the listBox_{event} methods.
Code:

using System.Windows.Forms;

namespace dragDrop
{
public partial class Form1 : Form
{
bool willDrag = false;
ListBox dragSource;
object dragSourceSelection;

public Form1()
{
InitializeComponent();
}
private void listBox_MouseDown(object sender, MouseEventArgs e)
{
willDrag = true;
}
private void listBox_DragDrop(object sender, DragEventArgs e)
{
ListBox lbSender = (ListBox)sender;
lbSender.Items.Add(e.Data.GetData(typeof(string)));
dragSource.Items.Remove(dragSourceSelection);
}
private void listBox_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void listBox_MouseUp(object sender, MouseEventArgs e)
{
willDrag = false;
}
private void listBox_MouseMove(object sender, MouseEventArgs e)
{
if (!willDrag) return;
willDrag = false;
ListBox lbSender = (ListBox)sender;
if (lbSender.SelectedItem == null) return;
lbSender.DoDragDrop(lbSender.SelectedItem, DragDropEffects.Move);
dragSource = lbSender;
dragSourceSelection = lbSender.SelectedItem;
}
}
}

Note that I am removing the item on the DragDrop. This prevents losing data
when the string is moved outside the droppable area and dropped.
 
J

JTC^..^

What I have here produces unexpected results.
I have two ListBoxes both of their events are the listBox_{event} methods..
Code:

using System.Windows.Forms;

namespace dragDrop
{
    public partial class Form1 : Form
    {
        bool willDrag = false;
        ListBox dragSource;
        object dragSourceSelection;

        public Form1()
        {
            InitializeComponent();
        }
        private void listBox_MouseDown(object sender, MouseEventArgs e)
        {
            willDrag = true;
        }
        private void listBox_DragDrop(object sender, DragEventArgs e)
        {
            ListBox lbSender = (ListBox)sender;
            lbSender.Items.Add(e.Data.GetData(typeof(string)));
            dragSource.Items.Remove(dragSourceSelection);
        }
        private void listBox_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
        }
        private void listBox_MouseUp(object sender, MouseEventArgs e)
        {
            willDrag = false;
        }
        private void listBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (!willDrag) return;
            willDrag = false;
            ListBox lbSender = (ListBox)sender;
            if (lbSender.SelectedItem == null) return;
            lbSender.DoDragDrop(lbSender.SelectedItem, DragDropEffects.Move);
            dragSource = lbSender;
            dragSourceSelection = lbSender.SelectedItem;
        }
    }

}

Note that I am removing the item on the DragDrop. This prevents losing data
when the string is moved outside the droppable area and dropped.

public partial class Form1 : Form
{
bool willDrag = false;
ListBox dragSource;

public Form1()
{
InitializeComponent();

this.listBox1.AllowDrop = true;
this.listBox2.AllowDrop = true;

this.listBox1.Items.Add("Item1");
this.listBox1.Items.Add("Item2");
}
private void listBox_MouseDown(object sender, MouseEventArgs
e)
{
willDrag = true;
dragSource = (ListBox)sender;
}
private void listBox_DragDrop(object sender, DragEventArgs e)
{
ListBox lbSender = (ListBox)sender;
object item = e.Data.GetData(typeof(string));
lbSender.Items.Add(item);

dragSource.Items.RemoveAt(dragSource.SelectedIndex);

}
private void listBox_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}

private void listBox_MouseUp(object sender, MouseEventArgs e)
{
willDrag = false;
}
private void listBox_MouseMove(object sender, MouseEventArgs
e)
{
if (!willDrag) return;
willDrag = false;
ListBox lbSender = (ListBox)sender;
if (lbSender.SelectedItem == null) return;
lbSender.DoDragDrop(lbSender.SelectedItem,
DragDropEffects.Move);
}

}
 
W

wannabe geek

--

Wannabe Geek


JTC^..^ said:
public partial class Form1 : Form
{
bool willDrag = false;
ListBox dragSource;

public Form1()
{
InitializeComponent();

this.listBox1.AllowDrop = true;
this.listBox2.AllowDrop = true;

this.listBox1.Items.Add("Item1");
this.listBox1.Items.Add("Item2");
}
private void listBox_MouseDown(object sender, MouseEventArgs
e)
{
willDrag = true;
dragSource = (ListBox)sender;
}
private void listBox_DragDrop(object sender, DragEventArgs e)
{
ListBox lbSender = (ListBox)sender;
object item = e.Data.GetData(typeof(string));
lbSender.Items.Add(item);

dragSource.Items.RemoveAt(dragSource.SelectedIndex);
If RemoveAt works to always remove the dragged item, that is what I want.
I'll try it. I'm still curious why my previous code did not remove the item
every time.
 
J

JTC^..^

If RemoveAt works to always remove the dragged item, that is what I want.
I'll try it. I'm still curious why my previous code did not remove the item
every time.

In your original code, the dragSourceSelection was null the very first
time you dragdrop drop. Therefore the item is not selected when the
MouseMove event is fired (which is where you set the selected item).
The second time you drag it, the dragSourceSelection is actually the
first item you moved.

Actually there are several ways this code could have been refactored,
but the key was not set the selected item in the MouseMove event. By
getting the selected index (or item) in the drag drop event, you can
be sure the item you want to remove has been selected.
 
J

JTC^..^

In your original code, the dragSourceSelection was null the very first
time you dragdrop drop. Therefore the item is not selected when the
MouseMove event is fired (which is where you set the selected item).
The second time you drag it, the dragSourceSelection is actually the
first item you moved.

Actually there are several ways this code could have been refactored,
but the key was not set the selected item in the MouseMove event. By
getting the selected index (or item) in the drag drop event, you can
be sure the item you want to remove has been selected.

I must admit I was rather puzzled, as I couldn't step though and debug
the mouseevents, but that is the best explaination I could see. Anyway
when I changed the code it worked.
 
W

wannabe geek

JTC^..^ said:
In your original code, the dragSourceSelection was null the very first
time you dragdrop drop. Therefore the item is not selected when the
MouseMove event is fired (which is where you set the selected item).
The second time you drag it, the dragSourceSelection is actually the
first item you moved.

I see that now.
Actually there are several ways this code could have been refactored,
but the key was not set the selected item in the MouseMove event.

No, the key was to understand that DoDragDrop is a suspended operation.
By getting the selected index (or item) in the drag drop event, you can
be sure the item you want to remove has been selected.

.

Thank you. Although I did not use your code your mention of stepping through
code led me to do it myself. There I discovered my problem. I set a
breakpoint in the DragDrop event handler. While I was stepping through that,
I noticed that the line of code calling DoDragDrop was highlighted in gray.
Ah! So I moved it to the end of the MouseMove, an that completely fixed my
problem.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top