Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
60
Drag and drop functionality within a single UltraListView
posted

How do we implement the drag and drop functionality within a UltraListView control? Our requirement is to rearrange the order of UltraListViewItems within a given UltraListView control by dragging and dropping them.

Any code sample or snippet demonstrating the concept would be very helpful. I have already to achieve this functionality only without any success, so far.

Shashi

  • 69832
    Offline posted

    I only had time for a quick & dirty example but this demonstrates the basic approach. You can use the 'WinListView DragDrop' sample for direction on refining this.

    this.listView.AllowDrop = true;
    this.listView.MouseDown += new MouseEventHandler(listView_MouseDown);
    this.listView.MouseMove += new MouseEventHandler(listView_MouseMove);
    this.listView.DragOver += new DragEventHandler(listView_DragOver);
    this.listView.DragDrop += new DragEventHandler(listView_DragDrop);
    this.listView.QueryContinueDrag += new QueryContinueDragEventHandler(listView_QueryContinueDrag);


    private Nullable<Point> lastMouseDown = null;
    private UltraListViewItem dragItem = null;
    private UltraListViewItem dropItem = null;

    private void listView_MouseDown(object sender, MouseEventArgs e)
    {
        //  Record the cursor location
        if ( e.Button == MouseButtons.Left )
            this.lastMouseDown = e.Location;
        else
            this.lastMouseDown = null;
    }

    private void listView_MouseMove(object sender, MouseEventArgs e)
    {
        UltraListView listView = sender as UltraListView;


        //  If the mouse has moved outside the area in which it was pressed,
        //  start a drag operation
        if ( this.lastMouseDown.HasValue )
        {
            Size dragSize = SystemInformation.DragSize;
            Rectangle dragRect = new Rectangle( this.lastMouseDown.Value, dragSize );
            dragRect.X -= dragSize.Width / 2;
            dragRect.Y -= dragSize.Height / 2;

            if (dragRect.Contains(e.Location) )
            {
                UltraListViewItem itemAtPoint = listView.ItemFromPoint( e.Location );

                if ( itemAtPoint != null )
                {
                    this.lastMouseDown = null;
                    this.dragItem = itemAtPoint;
                    listView.DoDragDrop( this.dragItem, DragDropEffects.Move );
                }
            }
        }
    }

    private void listView_QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
    {
        UltraListView listView = sender as UltraListView;

        //  Cancel the drag operation if the escape key was pressed
        if ( e.EscapePressed )
        {
           this.OnDragEnd( listView, true );
           e.Action = DragAction.Cancel;
        }
    }

    private void listView_DragOver(object sender, DragEventArgs e)
    {           
        UltraListView listView = sender as UltraListView;
        Point clientPos = listView.PointToClient( new Point(e.X, e.Y) );

        if ( this.dragItem != null )
        {
            this.dropItem = listView.ItemFromPoint( clientPos );

            e.Effect = this.dropItem != null && this.dropItem != this.dragItem ? DragDropEffects.Move : DragDropEffects.None;
        }

        //  TODO: This could be improved with a hover timer

        //  If the cursor is within {dragScrollAreaHeight} pixels
        //  of the top or bottom edges of the control, scroll
        int dragScrollAreaHeight = 8;

        Rectangle displayRect = listView.DisplayRectangle;
        Rectangle topScrollArea = displayRect;
        topScrollArea.Height = (dragScrollAreaHeight * 2);

        Rectangle bottomScrollArea = displayRect;
        bottomScrollArea.Y = bottomScrollArea.Bottom - dragScrollAreaHeight;
        bottomScrollArea.Height = dragScrollAreaHeight;

        ISelectionManager selectionManager = listView as ISelectionManager;
        if ( topScrollArea.Contains(clientPos) || bottomScrollArea.Contains(clientPos) )
            selectionManager.DoDragScrollVertical(0);
    }

    private void listView_DragDrop(object sender, DragEventArgs e)
    {
        UltraListView listView = sender as UltraListView;
        this.OnDragEnd( listView, false );
    }

    private void OnDragEnd( UltraListView listView, bool canceled )
    {
        if ( canceled == false && this.dragItem != null && this.dropItem != null )
        {
            listView.BeginUpdate();

            listView.Items.Remove( this.dragItem );
            int index = this.dropItem.Index + 1;
            listView.Items.Insert( index, this.dragItem );

            listView.EndUpdate();
        }

        this.dragItem = this.dropItem = null;
        this.lastMouseDown = null;
    }