Drag and drop labels in a panel

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
 
S

Stoitcho Goutsev \(100\)

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?
 
B

Blkpower

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
 
P

Paul E Collins

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();
}
}
 
S

Stoitcho Goutsev \(100\)

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
 
B

Blkpower

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
 
B

Blkpower

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

Top