views:

655

answers:

4

Is there a way that one can make a control, such as a textbox, drag-droppable in C#?

I want the user to have the ability to click and hold the control with the mouse and drag it around on its surface and drop it anywhere within that surface.

Anyone has any idea how to implement this?

+1  A: 

If your control is moving within one container (e.g. panel), you can override OnMouseDown / OnMouseMove events, and adjust the Location property of the control.

Based on your question, it does not seem that you need full drag-and-drop (moving data between different controls or even applications).

dbkk
True, I don't need to move data between any controls or apps, just move the control within its container...
Tony
A: 

if you're trying to drag an item from outside the silverlight container, then your best bet is to check out silverlight 4 beta

public MainPage()
 {
     InitializeComponent();
     Loaded += new RoutedEventHandler(MainPage_Loaded);   
     // wire up the various Drop events
     InstallButton.Drop += new DragEventHandler(InstallButton_Drop);
     InstallButton.DragOver += new DragEventHandler(InstallButton_DragOver);
     InstallButton.DragEnter += new DragEventHandler(InstallButton_DragEnter);
     InstallButton.DragLeave += new DragEventHandler(InstallButton_DragLeave);
 }

 void InstallButton_Drop(object sender, DragEventArgs e)
 {
     IDataObject foo = e.Data; // do something with data
 }
Neil
+2  A: 

This answer helped me a lot. It's working great on any type of Control and Container.

Marcel Benthin
A: 

This used to be so easy in VB6. But now we really only have what used to be called OleDrag.

Anyway, the following code should show you how. You just need a single label (dragDropLabel), and set the AllowDrop property of the form (DragDropTestForm) to True.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace DragDropTest
{
    public partial class DragDropTestForm : Form
    {
     // Negative offset to drop location, to adjust for position where a drag starts
     // on a label.
     private Point _labelOffset;

     // Save the full type name for a label, since this is used to test for the control type.
     private string labelTypeName = typeof(Label).FullName;

     public DragDropTestForm()
     {
      InitializeComponent();
     }

     private void dragDropLabel_MouseDown(object sender, MouseEventArgs e)
     {
      if (e.Button == MouseButtons.Left)
      {
       _labelOffset = new Point(-e.X, -e.Y);
      }
     }

     private void dragDropLabel_MouseMove(object sender, MouseEventArgs e)
     {
      const double minimumDragDistance = 4;
      const double minimumDragDistanceSquared = minimumDragDistance * minimumDragDistance;

      if (e.Button == MouseButtons.Left)
      {
       // Minimum n pixel movement before drag starts.
       if (((Math.Pow(_labelOffset.X - e.X, 2)) + Math.Pow(_labelOffset.Y - e.Y, 2)) >= minimumDragDistanceSquared)
       {
        dragDropLabel.DoDragDrop(dragDropLabel, DragDropEffects.Move);
       }
      }  
     }

     private void DragDropTestForm_DragOver(object sender, DragEventArgs e)
     {
      IDataObject data = e.Data;

      string[] formats = data.GetFormats();

      if (formats[0] == labelTypeName)
      {
       e.Effect = DragDropEffects.Move;
      }
     }

     private void DragDropTestForm_DragDrop(object sender, DragEventArgs e)
     {
      IDataObject data = e.Data;

      string[] formats = data.GetFormats();

      if (formats[0] == labelTypeName)
      {
       Label label = (Label) data.GetData(formats[0]);
       if (label == dragDropLabel)
       {
        Point newLocation = new Point(e.X, e.Y);
        newLocation.Offset(_labelOffset);
        dragDropLabel.Location = this.PointToClient(newLocation);
       }
      }
     }
    }
}
Mark Bertenshaw
Ok - is it my imagination, or was this originally nothing to do with Silverlight? In which case, ignore this - it is WinForms only.
Mark Bertenshaw