Collaborate without boundaries

Development Romance

WPF, C# and Silverlight

WPF: Drag and drop between listboxes

  • Comments 14

In this post we saw the way to drop files in a WPF window, now we are going to see a way to drag and drop items between listboxes. Lets say tha we have 2 listboxes in a window and we like to take items from the first one and drop them in the second one. So, i think it’s time for some coding…open visual studio, create a new WPF project and add 2 listboxes like the following ones:

 

        <ListBox Name="List1" Width="150" HorizontalAlignment="Left">
            <ListBoxItem>1</ListBoxItem>
            <ListBoxItem>2</ListBoxItem>
            <ListBoxItem>3</ListBoxItem>
            <ListBoxItem>4</ListBoxItem>
            <ListBoxItem>5</ListBoxItem>
        </ListBox>
        <ListBox Name="List2" Width="150" HorizontalAlignment="Right" />

Now, we have created the 2 listboxes in which the left one, in the window, contains the items to be dragged and the right one the items to be dropped. We must handle 3 situations:

  1. When the left mouse button is pressed upon a listbox item.
  2. The left mouse button remains pressed and the item is “dragged”.
  3. The left mouse button is released upon the second list and the item is “dropped”.

In order to handle the 1st situation we must handle the PreviewMouseLeftButtonDown event of the first listbox and if the the mouse hits a listbox item, then the drag operation proceeds. Create a handler for the first listbox’s PreviewMouseLeftButtonDown event. Now the first listbox should look like this:

        <ListBox Name="List1" Width="150" HorizontalAlignment="Left"
                 PreviewMouseLeftButtonDown="List1_PreviewMouseLeftButtonDown">
            <ListBoxItem>1</ListBoxItem>
            <ListBoxItem>2</ListBoxItem>
            <ListBoxItem>3</ListBoxItem>
            <ListBoxItem>4</ListBoxItem>
            <ListBoxItem>5</ListBoxItem>
        </ListBox>

In the window’s code behind class add the following private variable:

private ListBoxItem _dragged;

In the handler function add the following code:

 

          private void List1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (_dragged != null)
                return;

            UIElement element = List1.InputHitTest(e.GetPosition(List1)) as UIElement;

            while (element != null)
            {
                if (element is ListBoxItem)
                {
                    _dragged = (ListBoxItem)element;
                    break;
                }
                element = VisualTreeHelper.GetParent(element) as UIElement;
            }
        }

In this procedure, we get the exact element that is pointed by the mouse pointer and search its parents until the listbox item object is found. If no such object is found, then the drag operation doesn’t proceeds.

Now, it’s time to handle the 2nd situation. The item to be dragged has been chosen and we must do the drag operation. In order to handle this we must handle the MouseMove event of the window, so add a handler function for it:

 

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        MouseMove="Window_MouseMove">

 

and in the handler function add the following code:

 

         private void Window_MouseMove(object sender, MouseEventArgs e)
        {
            if (_dragged == null)
                return;
            if (e.LeftButton == MouseButtonState.Released)
            {
                _dragged = null;
                return;
            }

            DataObject obj = new DataObject(DataFormats.Text, _dragged.ToString());
            DragDrop.DoDragDrop(_dragged, obj, DragDropEffects.All);
        }

In this procedure, if an item is dragged and the left mouse button is still pressed, then do drag operation for the currently dragged listbox item.

And now, it’s time to handle tha 3rd and final situation. We must let the right list to allow drop and handle the appropriate drop events. Change the list’s AllowDrop property value to True and create handler functions for the DragEnter, DragOver and Drop events:

<ListBox Name="List2" Width="150" HorizontalAlignment="Right"
                 AllowDrop="True" DragEnter="List2_DragEnter"
                 DragOver="List2_DragEnter" Drop="List2_Drop"/>

add the following code to the List2_DragEnter function:

          private void List2_DragEnter(object sender, DragEventArgs e)
        {
            if (_dragged == null || e.Data.GetDataPresent(DataFormats.Text, true) == false)
                e.Effects = DragDropEffects.None;
            else
                e.Effects = DragDropEffects.All;
        }

The only accepted dropped item is the first list’s dragged text item. Add the following code to the Drop event’s handler function:

 

        private void List2_Drop(object sender, DragEventArgs e)
        {
            List1.Items.Remove(_dragged);
            List2.Items.Add(_dragged);
        }

The dragged item is removed from the left list and is added to the right list.

Run the application and try some drag and drops to test it. See you next time !!

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Post
Page 1 of 1 (14 items)
Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Post