Click here to Skip to main content
14,363,089 members
Rate this:
Please Sign up or sign in to vote.
See more:
How to show the custom user control(s) in flow layout panel dragging and at the same with a move icon mouse cursor in Winforms in c#?

I have been working on a Winforms Application and is using drag and drop functionality. I have the drag and drop functionality working, but need to make it more intuitive and user friendly.

Part of this will involve actually showing the item being dragged, preferably semi-transparent when dragging and also considered with the mouse down location at the item. What is the easiest way to do this?

The items I am dragging are custom user control(s) with text, pictures, data auto-created and in flow layout panel,but I am not even sure where to look for how to do this. I added my code worked here :

A) In the main form :
public main_form()
    {
        InitializeComponent();
        flowLayoutPanel1.AllowDrop = true;
        flowLayoutPanel1.DragDrop += new DragEventHandler(this.flowLayoutPanel1_DragDrop);
        flowLayoutPanel1.DragEnter += new DragEventHandler(this.flowLayoutPanel1_DragEnter);
        foreach (uploaded_items c in flowLayoutPanel1.Controls)
            c.MouseDown += new MouseEventHandler(c_MouseDown); 
    }

    private void c_MouseDown(object sender, MouseEventArgs e)
    {
        uploaded_items data=new uploaded_items();
        foreach (uploaded_items c in flowLayoutPanel1.Controls)
        {
              if (c._isDragging == true) data = c; 
        }
        Bitmap bmp = new Bitmap(data.Size.Width, data.Size.Height);
        data.DrawToBitmap(bmp, new Rectangle(Point.Empty, bmp.Size));
        bmp.MakeTransparent(Color.White);
        Cursor cur = new Cursor(bmp.GetHicon());
        Cursor.Current = cur;
    }

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

    private void flowLayoutPanel1_DragDrop(object sender, DragEventArgs e)
    {
        uploaded_items data = (uploaded_items)e.Data.GetData(typeof(uploaded_items));
        FlowLayoutPanel _destination = (FlowLayoutPanel)sender;
        Point p = _destination.PointToClient(new Point(e.X, e.Y));
        var item = _destination.GetChildAtPoint(p);
        int index = _destination.Controls.GetChildIndex(item, false);
        _destination.Controls.SetChildIndex(data, index);
        _destination.Invalidate();
}

B) In the user control :
public partial class uploaded_items : UserControl
{
    public uploaded_items()
    {
        InitializeComponent();
        AllowDrag = true;
    }

    public bool AllowDrag { get; set; }
    public bool _isDragging = false;
    private int _DDradius = 4;  //the min distance the mouse req to dragged so that drag action would be taken 
    private int _mX = 0;        //positon on mouse down
    private int _mY = 0;

    protected override void OnGotFocus(EventArgs e)
    {
        this.BackColor = Color.SandyBrown;
        base.OnGotFocus(e);
    }

    protected override void OnLostFocus(EventArgs e)
    {
        this.BackColor = Color.Transparent;
        base.OnLostFocus(e);
    }

    protected override void OnClick(EventArgs e)
    {
        this.Focus();
        base.OnClick(e);
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        this.Focus();
        base.OnMouseDown(e);
        _mX = e.X;
        _mY = e.Y;
        this._isDragging = false; 
    } 

    protected override void OnMouseMove(MouseEventArgs e)
    {
        if (!_isDragging)
        {
            // This is a check to see if the mouse is moving while pressed.
            // Without this, the DragDrop is fired directly when the control is clicked, now I have to drag a few pixels first.
            if (e.Button == MouseButtons.Left && _DDradius > 0 && this.AllowDrag)
            {
                int dist_x_dragged = e.X - _mX ;
                int dist_y_dragged = e.Y - _mY ;
                if (((dist_x_dragged ^ 2) + (dist_y_dragged ^ 2)) > _DDradius)
                {
                    DoDragDrop(this, DragDropEffects.All);
                    _isDragging = true;
                    return;
                }
            }
            base.OnMouseMove(e);
        } 
    }

    protected override void OnMouseUp (MouseEventArgs e)
    {
        _isDragging = false;
        base.OnMouseUp(e);
    }

    #region Properties
    private string _title;
    private string _msg;
    private Image _icon;
    [Category("Custom Props")]
    public string title
    {
        get { return _title; }
        set { _title = value; lbl_title.Text = value; }
    }
    [Category("Custom Props")]
    public string msg
    {
        get { return _msg; }
        set { _msg = value; lbl_msg.Text = value; }
    }
    [Category("Custom Props")]
    public Image icon
    {
        get { return _icon; }
        set { _icon = value; pictureBox1.Image = value; }
    }
    #endregion
}


What I have tried:

The primary drag and drop function is ok, but I found I could not show the control / picture of the control dragging in this scheme:

1. Limited area covered: 
the bmp only appears when it's mouse down and dragged "carefully" on the user control, and it's only limited on the user control but not the text/ picture on the user control or the flow layout panel

2. When I try to drag, the bmp disappeared

3. the bmp is centered at mouse instantaneous location, but I wish it situated at the location at which the mouse initially down on the user control
Posted
Updated 22-Oct-19 4:32am
v3

1 solution

Rate this:
Please Sign up or sign in to vote.

Solution 1

Change the "cursor shape" (while dragging, etc).

Enable Your Windows Forms Applications to Drag-and-Drop Data Objects[^]
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100