Drag & Drop example

8 posts, 0 answers
  1. tom
    tom avatar
    15 posts
    Member since:
    May 2011

    Posted 16 Aug 2011 Link to this post

    Hi,

    I can't find an example for the RadListView and Drag & Drop items for reordering.
    I am also missing some visual aids during the drop event like in the GridViews Row Drag&Drop example.

    Regards,
    Tom
  2. Ivan Todorov
    Admin
    Ivan Todorov avatar
    688 posts

    Posted 17 Aug 2011 Link to this post

    Hello Tom,

    Thank you for writing.

    Currently, RadListView does not support drag & drop row reorder out of the box. You can implement it by using the standard Windows Forms drag and drop mechanism as it is demonstrated below:
    public partial class Form2 : Form
    {
        Point? lastMouseDownLocation;
     
        public Form2()
        {
            InitializeComponent();
     
            radListView1.AllowDrop = true;
            radListView1.MouseDown += new MouseEventHandler(radListView1_MouseDown);
            radListView1.MouseMove += new MouseEventHandler(radListView1_MouseMove);
            radListView1.DragDrop += new DragEventHandler(radListView1_DragDrop);
            radListView1.DragEnter += new DragEventHandler(radListView1_DragEnter);
            radListView1.MultiSelect = true;
        }
     
        void radListView1_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
        }
     
        void radListView1_DragDrop(object sender, DragEventArgs e)
        {
            IDataObject dataObject = e.Data;
            if (dataObject != null)
            {
                List<ListViewDataItem> selectedItems = dataObject.GetData(typeof(List<ListViewDataItem>)) as List<ListViewDataItem>;
                if (selectedItems != null)
                {
                    for (int i = 0; i < selectedItems.Count; i++)
                    {
                        ListViewDataItem item = selectedItems[i];
                           
                        radListView1.Items.Remove(item);
     
                        BaseListViewVisualItem it = radListView1.ElementTree.GetElementAtPoint(radListView1.ListViewElement.PointFromScreen(new Point(e.X, e.Y))) as BaseListViewVisualItem;
                        if (it != null)
                        {
                            int indexToMoveTo = radListView1.Items.IndexOf(it.Data);
                            Insert(radListView1, indexToMoveTo, item);
     
                        }
                        else
                        {
                            radListView1.Items.Add(item);
                        }
                    }
                }
                dataObject = null;
            }
        }
     
        private void Insert(RadListView listViewDrop, int indexToMoveTo, ListViewDataItem item)
        {
            Stack<ListViewDataItem> movedItems = new Stack<ListViewDataItem>();
     
            while (listViewDrop.Items.Count > indexToMoveTo)
            {
                movedItems.Push(listViewDrop.Items[listViewDrop.Items.Count - 1]);
                listViewDrop.Items.Remove(listViewDrop.Items[listViewDrop.Items.Count - 1]);
            }
     
            listViewDrop.Items.Add(item);
     
            while (movedItems.Count > 0)
            {
                listViewDrop.Items.Add(movedItems.Pop());
            }
        }
     
        void radListView1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left &&
            this.lastMouseDownLocation != null &&
            radListView1.SelectedItems.Count > 0)
            {
                Point cursorPos = new Point(e.X, e.Y);
                Point dragPoint = (Point)this.lastMouseDownLocation;
     
                Rectangle dragRect = new Rectangle(dragPoint,
                SystemInformation.DragSize);
                dragRect.X -= (int)(SystemInformation.DragSize.Width / 2);
                dragRect.Y -= (int)(SystemInformation.DragSize.Height / 2);
     
                if (dragRect.Contains(cursorPos) == false)
                {
                    radListView1.Capture = false;
                    List<ListViewDataItem> selectedItems = radListView1.SelectedItems.ToList<ListViewDataItem>();
     
                    radListView1.DoDragDrop(selectedItems, DragDropEffects.Move);
                }
            }
        }
     
        void radListView1_MouseDown(object sender, MouseEventArgs e)
        {
            BaseListViewVisualItem itemAtPoint = radListView1.ElementTree.GetElementAtPoint(e.Location) as BaseListViewVisualItem;
            if (itemAtPoint != null)
                this.lastMouseDownLocation = new Point(e.X, e.Y);
            else
                this.lastMouseDownLocation = null;
        }
    }

    For your convenience, I have logged this as a feature request in PITS so you can subscribe and vote for it. As it gets more votes, we will consider implementing it with higher priority in the future releases.

    Your Telerik points have been updated for requesting this feature.

    Greetings,
    Ivan Todorov
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get now >>

  3. UI for WinForms is Visual Studio 2017 Ready
  4. tom
    tom avatar
    15 posts
    Member since:
    May 2011

    Posted 18 Aug 2011 Link to this post

    Hello Ivan,

    thank you this example was very helpfull.

    But one question is not answered: the RadGridView has the possibility to show a drag image or hint during dragging. Do you know also a simple workaround for this?

    Best regards,
    Tom
  5. Ivan Todorov
    Admin
    Ivan Todorov avatar
    688 posts

    Posted 19 Aug 2011 Link to this post

    Hello Tom,

    You can add the following code to the class in my previous post in order to get a custom drag cursor:

    Cursor textcursor;
     
    public static Bitmap SetOpacity(Bitmap original, float opacity)
    {
        Bitmap temp = new Bitmap(original.Width, original.Height);
        Graphics g = Graphics.FromImage(temp);
        ColorMatrix cm = new ColorMatrix();
        cm.Matrix33 = opacity;
     
        ImageAttributes ia = new ImageAttributes();
        ia.SetColorMatrix(cm, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
        g.DrawImage(original, new Rectangle(0, 0, temp.Width, temp.Height), 0, 0, original.Width, original.Height, GraphicsUnit.Pixel, ia);
        g.Dispose();
     
        return temp;
    }
     
    public void Drawcursor(DragEventArgs e)
    {
        IDataObject dataObject = e.Data;
        if (dataObject == null)
        {
            return;
        }
     
        List<ListViewDataItem> selectedItems = dataObject.GetData(typeof(List<ListViewDataItem>)) as List<ListViewDataItem>;
        if (selectedItems == null || selectedItems.Count == 0)
        {
            return;
        }
     
        RadElement element = this.radListView1.ListViewElement.ViewElement.GetElement(selectedItems[0]);
     
        Bitmap bmp = SetOpacity(element.GetAsBitmapEx(Color.Transparent, 0, new SizeF(1, 1)), 0.5f);
         
        textcursor = new Cursor(bmp.GetHicon());
     
        bmp.Dispose();
    }
     
    void radListView1_GiveFeedback(object sender, GiveFeedbackEventArgs e)
    {
        e.UseDefaultCursors = false;
        Cursor.Current = textcursor;
    }
     
    void radListView1_DragEnter(object sender, DragEventArgs e)
    {
        e.Effect = DragDropEffects.Move;
        Drawcursor(e);
    }

    I hope this is useful. Feel free to ask if you have any further questions.

    Best wishes,
    Ivan Todorov
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get now >>

  6. tom
    tom avatar
    15 posts
    Member since:
    May 2011

    Posted 22 Aug 2011 Link to this post

    Hi Ivan,

    many thanks for your fantastic code snippets. They are very helpfull and instructive.

    So I feel a little bit bad, if I ask you for some further help.
    The dragging image is one solved request, but it would be very nice, if the user could see the insertion point of the dropped items dynamically. I think something like a insertion cue. Maybe only one bold line at the top,left,right or bottom of an item, showing the possibility of insertion.

    Many thanks in advance.

    Best regards,
    Tom
  7. Ivan Todorov
    Admin
    Ivan Todorov avatar
    688 posts

    Posted 25 Aug 2011 Link to this post

    Hi Tom,

    I am glad that you find my answer helpful. Please do not hesitate to contact us, ask questions or leave feedback whenever you need to. Our team is always ready to help.

    As to your question, you can display some kind of visual clue of the insertion point by handling the following events:

    void radListView1_DragOver(object sender, DragEventArgs e)
    {
        Point location = this.radListView1.PointToClient(new Point(e.X, e.Y));
     
        this.radListView1.ListViewElement.SynchronizeVisualItems();
     
        BaseListViewVisualItem visual = this.radListView1.ElementTree.GetElementAtPoint(location) as BaseListViewVisualItem;
     
        if (visual != null)
        {
            visual.BackColor = Color.Red;
            visual.NumberOfColors = 1;
        }
     
        this.radListView1.ListViewElement.Update(RadListViewElement.UpdateModes.InvalidateItems);
    }
     
    void radListView1_VisualItemFormatting(object sender, ListViewVisualItemEventArgs e)
    {
        e.VisualItem.ResetValue(LightVisualElement.BackColorProperty, ValueResetFlags.Local);
        e.VisualItem.ResetValue(LightVisualElement.NumberOfColorsProperty, ValueResetFlags.Local);
    }

    Using the same approach you can set every property of the visual item you need. Please have in mind that you have to reset its local setting in the VisualItemFormatting event.

    Indeed, such functionality will come very handy out of the box, so we might expect it to be introduced in the near future.

    Kind regards,
    Ivan Todorov
    the Telerik team

    Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

  8. Paul
    Paul avatar
    5 posts
    Member since:
    Feb 2012

    Posted 22 Jun 2012 Link to this post

    Could someone help me convert this to vb.net? I'm having the worst time trying to get it working.

    Thanks :)
  9. Stefan
    Admin
    Stefan avatar
    2891 posts

    Posted 27 Jun 2012 Link to this post

    Here you are Paul:
         Private Sub radListView1_DragOver(sender As Object, e As DragEventArgs)
        Dim location As Point = Me.radListView1.PointToClient(New Point(e.X, e.Y))
     
        Me.radListView1.ListViewElement.SynchronizeVisualItems()
     
        Dim visual As BaseListViewVisualItem = TryCast(Me.radListView1.ElementTree.GetElementAtPoint(location), BaseListViewVisualItem)
     
        If visual IsNot Nothing Then
            visual.BackColor = Color.Red
            visual.NumberOfColors = 1
        End If
     
        Me.radListView1.ListViewElement.Update(RadListViewElement.UpdateModes.InvalidateItems)
    End Sub
     
    Private Sub radListView1_VisualItemFormatting(sender As Object, e As ListViewVisualItemEventArgs)
        e.VisualItem.ResetValue(LightVisualElement.BackColorProperty, ValueResetFlags.Local)
        e.VisualItem.ResetValue(LightVisualElement.NumberOfColorsProperty, ValueResetFlags.Local)
    End Sub

    You can always use our free online converter for converting code between C# and VB.NET: http://converter.telerik.com/.

    I hope this helps.
     
    Regards,
    Stefan
    the Telerik team
    RadControls for WinForms Q2'12 release is now live! Check out what's new or download a free trial >>
Back to Top
UI for WinForms is Visual Studio 2017 Ready