Drag Drop Custom Control

I have created a panel that contains custom controls. Currently I can drag and drop them without any graphics and all is good.

I implemented the ImageList_DragBegin routines (DragEnd, DragLeave, DragEnter, etc) into the code and it works with one exception.

When the control is dragged across other controls in the panel, the controls are not repainted correctly and there are traces of dragged image left behind. (See Drag2)

Drag 1 (Everything looks good) //www.attitude.com/users/lee/drag1.gif

Drag 2 (Drag residue left from image) www.attitude.com/users/lee/drag2.gif

This is written in VB.Net 2.0 and references a C# helper class for the dragging as seen in most treeview examples.

My drag_enter/leave/dragend/dragbegin are all in the right place as far as I can tell. I have not repainting going on or changing in states of any control.

I also tried repainting everything on the screen just to see what happens. as you can tell from looking inside the drag image, doing a repaint of a region would only affect those items inside the image, but the residual image is being left.

I'm still pretty new at this, so is there something I'm missing

Any help would be appreciated.



Answer this question

Drag Drop Custom Control

  • Mustansir - MSFT

    Ok, I solved the issue by looking at the other examples. It seems that doing the dragmove during the DragOver event was not the best idea. I moved the dragmove to a timer and let it redraw. I do see artifacts on some rare occasion, but I'm more frustrated by the limitation of the size of the image that can be dragged.


  • beezleinc

    Typical drag in Windows changing cursor only, which is really simple way. But professional apps must display dragged objects. Windows have bad support for transparency effects, so best way to simulate drag is to create layered window (form with transparency set to 50%) and drag this window. But this is a little harder.


  • Michael Stephenson UK

    Hi!

    I am using Win32 Image List API to drag things, here is C# class that used for it:

    public class DragImage : IDisposable

    {

    #region IDisposable Members

    public void Dispose()

    {

    Timer.Enabled = false;

    Timer.Dispose();

    ImageList_DragLeave(IntPtr.Zero);

    ImageList_EndDrag();

    ImageList.Dispose();

    }

    #endregion

    #region External

    [DllImport("COMCTL32.DLL")]

    static extern bool ImageList_BeginDrag(IntPtr himlTrack,int iTrack, int dxHotspot, int dyHotspot);

    [DllImport("COMCTL32.DLL")]

    static extern bool ImageList_DragEnter(IntPtr hwndLock, int x, int y);

    [DllImport("COMCTL32.DLL")]

    static extern bool ImageList_DragMove(int x, int y);

    [DllImport("COMCTL32.DLL")]

    static extern bool ImageList_DragLeave(IntPtr hwndLock);

    [DllImport("COMCTL32.DLL")]

    static extern void ImageList_EndDrag();

    #endregion

    public DragImage(Bitmap image, int dxHotspot, int dyHotspot)

    {

    ImageList.TransparentColor = Color.Magenta;

    ImageList.ImageSize = new Size(Math.Min(image.Width, 256), Math.Min(image.Height, 256));

    ImageList.ColorDepth = ColorDepth.Depth32Bit;

    ImageList.Images.Add(image);

    ImageList_BeginDrag(ImageList.Handle, 0, dxHotspot, dyHotspot);

    ImageList_DragEnter(IntPtr.Zero, Control.MousePosition.X, Control.MousePosition.Y);

    Timer.Tick += new EventHandler(OnTimerTick);

    Timer.Interval = 10;

    Timer.Enabled = true;

    }

    void OnTimerTick(object sender, EventArgs e)

    {

    ImageList_DragMove(Control.MousePosition.X, Control.MousePosition.Y);

    }

    System.Windows.Forms.ImageList ImageList = new System.Windows.Forms.ImageList();

    System.Windows.Forms.Timer Timer = new System.Windows.Forms.Timer();

    }

    and here is how I use it in drag operations (sample for ListView):

    void List_ItemDrag(object sender, ItemDragEventArgs e)

    {

    ListViewItem item = e.Item as ListViewItem;

    if (item == null) return;

    using (DragImage dragImage = new DragImage(

    List.SmallImageList.Images[item.ImageIndex] as Bitmap,

    List.SmallImageList.ImageSize.Width / 2,

    List.SmallImageList.ImageSize.Height / 2))

    {

    List.DoDragDrop(item.Tag, DragDropEffects.Link);

    }

    }

    this works with images up to 256x256 (limit of Image List API). In fact Windows have problems with transparency, hope Vista will fix it at last. May be you can simply turn off transparency, so dragging your control won't show such artefacts

    Anyway, if you post here some code you use and describe your drag method - we can find the way to help you.



  • Drag Drop Custom Control