Drag and drop labels in a panel

  • Thread starter Thread starter Blkpower
  • Start date Start date
B

Blkpower

Hi to all,

I'm writing a windows form application that has a panel with some
labels in it.
I need to let the user move these labels with drag and drop inside the
panel. How can I do it?
I now how to drag and drop for example the text contained in a textbox,
but not the whole control.
I read an article called "Fake drag and drop" that works without
dragdrop event and it's not so good.

Thanks in advance.
Vincent
 
Hi,

DnD is used to move data around, for example you select a text in one
application and you move it to some other application - you move the data.
The same effect you can get by copy/paste the text to/from the clipboard
If grab a window by its caption and start moving it around this has nothing
to do with drag and drop; there is no data that has been moved around.

So what you want to do - move the label's data (I guess the text) or you
want to move the lable control around just like you would move a window by
grabing it handle?
 
Hi,

thanks for your answer.
What I need to do is to move the whole control, not only the text.
Any ideas about how to do this?

Thanks
Vincent
 
Here's how I managed draggable PictureBoxes in a Panel.

I didn't use the normal drag/drop mechanisms at all; instead, I
handled the mouse events and used a timer to move the items. This
might be a stupid way to do it, but it works. Of course, you need to
connect up the piece_ event handlers for each separate item in your
Panel, which can be done with a simple foreach loop at the beginning.

Eq.


private PictureBox _draggedPiece;
private Point _dragLocation;

private void piece_MouseDown(object sender, MouseEventArgs e)
{
_draggedPiece = picPiece;
_draggedPiece.BringToFront();
}

private void piece_MouseUp(object sender, MouseEventArgs e)
{
_draggedPiece = null;
pnlMap.Invalidate();
}

private void piece_MouseMove(object sender, MouseEventArgs e)
{
if (_draggedPiece != null)
{
int x = _draggedPiece.Left + e.X;
int y = _draggedPiece.Top + e.Y;

_dragLocation = new Point(x, y);
}
}

private void tmrDragMove_Tick(object sender, System.EventArgs e)
{
// tmrDragMove is a Timer that fires many times a second

if (_draggedPiece != null)
{
_draggedPiece.Location = _dragLocation;
pnlMap.Invalidate();
}
}
 
Vincent,

Derive from the label control and override its WndProc

private const int WM_NCHITTEST = 0x84;
private const int HTCAPTION = 0x2;
private const int HTCLIENT = 0x1;


protected override void WndProc(ref Message m)
{
base.WndProc (ref m);
if(m.Msg == WM_NCHITTEST && m.Result == new IntPtr(HTCLIENT))
{
m.Result = new IntPtr(HTCAPTION);



}


That should work for any control
 
Here's how I managed draggable PictureBoxes in a Panel.

I didn't use the normal drag/drop mechanisms at all; instead, I
handled the mouse events and used a timer to move the items. This
might be a stupid way to do it, but it works. Of course, you need to
connect up the piece_ event handlers for each separate item in your
Panel, which can be done with a simple foreach loop at the beginning.

Eq.

private PictureBox _draggedPiece;
private Point _dragLocation;

private void piece_MouseDown(object sender, MouseEventArgs e)
{
_draggedPiece = picPiece;
_draggedPiece.BringToFront();

}

private void piece_MouseUp(object sender, MouseEventArgs e)
{
_draggedPiece = null;
pnlMap.Invalidate();

}

private void piece_MouseMove(object sender, MouseEventArgs e)
{
if (_draggedPiece != null)
{
int x = _draggedPiece.Left + e.X;
int y = _draggedPiece.Top + e.Y;

_dragLocation = new Point(x, y);
}

}

private void tmrDragMove_Tick(object sender, System.EventArgs e)
{
// tmrDragMove is a Timer that fires many times a second

if (_draggedPiece != null)
{
_draggedPiece.Location = _dragLocation;
pnlMap.Invalidate();
}



}- Nascondi testo tra virgolette -

- Mostra testo tra virgolette -

Hi,
thanks for your answer.
I found and example on internet called "Fakedraganddrop" very similar
to your solution. The problem is that is not so performant, I think I
can do it better.

Thanks
Vincent
 
Vincent,

Derive from the label control and override its WndProc

private const int WM_NCHITTEST = 0x84;
private const int HTCAPTION = 0x2;
private const int HTCLIENT = 0x1;

protected override void WndProc(ref Message m)
{
base.WndProc (ref m);
if(m.Msg == WM_NCHITTEST && m.Result == new IntPtr(HTCLIENT))
{
m.Result = new IntPtr(HTCAPTION);

}

That should work for any control

--
HTH








- Mostra testo tra virgolette -

Hi, thanks.
I tried as you suggested but was not able to see it working.
This is my class:

namespace UtilityConfigManager
{
public class MovingLabel: Label
{

private const int WM_NCHITTEST = 0x84;
private const int HTCAPTION = 0x2;
private const int HTCLIENT = 0x1;

public MovingLabel()
{
}

protected override void WndProc(ref Message m)
{
base.WndProc (ref m);
if(m.Msg == WM_NCHITTEST && m.Result == new IntPtr(HTCLIENT))
{
m.Result = new IntPtr(HTCAPTION);
}
}
}
}

and this is my form where I try to use the control:

public class Form2 : System.Windows.Forms.Form
{
private UtilityConfigManager.MovingLabel mlabel1;
private System.ComponentModel.Container components = null;

public Form2()
{
InitializeComponent();
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

private void InitializeComponent()
{
this.mlabel1 = new UtilityConfigManager.MovingLabel();
this.SuspendLayout();
//
// mlabel1
//
this.mlabel1.AllowDrop = true;
this.mlabel1.Location = new System.Drawing.Point(72, 48);
this.mlabel1.Name = "mlabel1";
this.mlabel1.TabIndex = 1;
this.mlabel1.Text = "mlabel1";
//
// Form2
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 273);
this.Controls.Add(this.mlabel1);
this.Name = "Form2";
this.Text = "Form2";
this.ResumeLayout(false);

}
}

Where Am I wrong?

Thanks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top