Drag and Drop Windows Forms: Controls disappear after dragging - c#

I need to drag labels between the panels. But when I'm trying to drop a label even within the initial panel, it disappears. Here is the code of the methods I use:
private void label1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
DoDragDrop(sender, DragDropEffects.All);
}
private void panel_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.All;
}
private void panel_DragDrop(object sender, DragEventArgs e)
{
Label src = e.Data.GetData(typeof(Label)) as Label;
src.Location = PointToClient(new Point(e.X, e.Y));
}
AllowDrop is enabled for the panels. Why do the labels disappear and how can I fix it?

The Label is still contained by the Form, so it is simply going behind the Panel.
Either...
(1) Bring the Label to the Front:
private void panel1_DragDrop(object sender, DragEventArgs e)
{
Label src = e.Data.GetData(typeof(Label)) as Label;
src.Location = this.PointToClient(new Point(e.X, e.Y));
src.BringToFront();
}
or,
(2) Make the Panel contain the Label, and adjust the coordinates to the Panel's client coord system:
private void panel1_DragDrop(object sender, DragEventArgs e)
{
Panel pnl = sender as Panel;
Label src = e.Data.GetData(typeof(Label)) as Label;
src.Location = pnl.PointToClient(new Point(e.X, e.Y));
pnl.Controls.Add(src);
}

Related

Drag and dropping a button (Button won't follow)

I'm having a bit of trouble making drag and drop a button in a panel and panel to recognize it and display Message with buttons name
So far I managed the part of dragging and dropping and recognizing however I'm missing the visual style of dragging, when I press with mouse it will just sit on the same place, it won't follow cursor. How do I make it follow the mouse?
public Form1()
{
InitializeComponent();
panel1.AllowDrop = true;
panel1.DragEnter += panel_DragEnter;
panel1.DragDrop += panel_DragDrop;
button1.MouseDown += button1_MouseDown;
}
private void button1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
button1.DoDragDrop(button1.Text, DragDropEffects.Copy | DragDropEffects.Move);
button1.Location= new Point(e.X, e.Y);
}
private void panel_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
if (e.Data.GetDataPresent(DataFormats.Text))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
private void panel_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
MessageBox.Show(e.Data.GetData(DataFormats.Text).ToString());
}
You'll have to keep in mind that the DoDragDrop method doesn't return the Position you dropped the object. The DragDrop event handles that.
To move the control while you're dragging you use the DragOver event of the panel. In the implementation you need to compensate for the fact that the X and Y coordinates in the EventArgs are Screen based while you need Clientbased coordinates to correctly position the control. The PointToClient is instrumental in that:
private void panel_DragOver(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(Button).FullName))
{
var draggedButton = (Button)e.Data.GetData(typeof(Button).FullName);
var screenpos = new Point(e.X, e.Y);
var clientPos = panel1.PointToClient(screenpos);
// calc offset
draggedButton.Location = new Point(
clientPos.X + panel1.Left,
clientPos.Y + panel1.Top);
}
}
Notice that your Data now contains the actual Button, instead of only the text. This makes that you can dragdrop multiple buttons, not only button1.
Your DragDrop event should now look like this:
private void panel_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(Button).FullName))
{
var draggedButton = (Button)e.Data.GetData(typeof(Button).FullName);
MessageBox.Show(draggedButton.Text);
var screenpos = new Point(e.X, e.Y);
var clientPos = panel1.PointToClient(screenpos);
draggedButton.Location = new Point(
clientPos.X + panel1.Left,
clientPos.Y + panel1.Top);
}
}
And DragEnter only slightly changed so it could handle the Button control instead of the text:
private void panel_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
if (e.Data.GetDataPresent(typeof(Button).FullName)) // button
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
And finally to get it all started and wired up the constructor code and the MouseDown implementation of the button:
public Form1()
{
InitializeComponent();
panel1.AllowDrop = true;
panel1.DragEnter += panel_DragEnter;
panel1.DragDrop += panel_DragDrop;
panel1.DragOver += panel_DragOver;
button1.MouseDown += button1_MouseDown;
}
private void button1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
button1.DoDragDrop(button1, DragDropEffects.Copy | DragDropEffects.Move);
}

how can i drag a label to a picturebox?

i want to drag a label2 and drop it into pictureBox1, however it didn't work and i don't know what the problem is
private void pictureBox1_DragDrop(object sender, DragEventArgs e)
{
pictureBox1.AllowDrop = true;
if (CurrentDrag.Equals("clock1"))
{
Label pnlDroggedTheme = (Label)sender;
pnlDroggedTheme.Height = pictureBox1.Height;
pnlDroggedTheme.Width = pictureBox1.Width;
label2.Visible = false;
correct++;
label1.Text = correct.ToString();
MessageBox.Show(" cerrect answer");
}
else
wronge++;
label1.Text = wronge.ToString();
MessageBox.Show("wronge answer");
}
this the DragEnter method for pictureBox1
private void pictureBox1_DragEnter(object sender, DragEventArgs e)
{
here it should copy data if the dropped element's data is from type string which is the label
if (e.Data.GetDataPresent(typeof(System.String)))
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
the label dragging works just fine but i can't drop it in the picturebox
private void label2_MouseDown(object sender, MouseEventArgs e)
{
CurrentDrag = "clock1";
Label labelV = (Label)sender;
labelV .DoDragDrop(labelV .BackColor, DragDropEffects.Copy);
}
You are making the drag drop event check if the type of data is System.String and perform no action if it isn't, Yet you are doing a drag drop for System.Color. What I think you want to do
Label labelV = (Label)sender;
labelV .DoDragDrop(labelV.Text, DragDropEffects.Copy);
You should either do that or modify your drag drop event to accept System.Color.
Also, you should move your pictureBox1.AllowDrop = true; to the constructor or Form_Load or just set the property to true at design time.

How to Drag, Drop and Resize Label on a Panel at runtime? C#, winForms

I have this code for dragging on a Panel but its not doing the thing.
I have to choose if I will just Drag&drop or Resize.
I think theres something wrong with my code here in form load.
Anyway I have 5 labels here and a panel named as label1, label2, label3, label4, label5 on panel1.
private void form_Load(object sender, EventArgs e)
{
//for drag and drop
//this.panel1.AllowDrop = true; // or Allow drop in the panel.
foreach (Control c in this.panel1.Controls)
{
c.MouseDown += new MouseEventHandler(c_MouseDown);
}
this.panel1.DragOver += new DragEventHandler(panel1_DragOver);
this.panel1.DragDrop += new DragEventHandler(panel1_DragDrop);
//end of drag and drop
}
void c_MouseDown(object sender, MouseEventArgs e)
{
Control c = sender as Control;
c.DoDragDrop(c, DragDropEffects.Move);
}
void panel1_DragDrop(object sender, DragEventArgs e)
{
Control c = e.Data.GetData(e.Data.GetFormats()[0]) as Control;
lblResizeAmtWord.Visible = false;
if (c != null)
{
c.Location = this.panel1.PointToClient(new Point(e.X, e.Y));
//this.panel1.Controls.Add(c); //disable if already on the panel
}
}
void panel1_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
I used the MouseDown, Up and Move Event of the Control I want to move. Let's say my control name is ctrlToMove.
private Point _Offset = Point.Empty;
private void ctrlToMove_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
_Offset = new Point(e.X, e.Y);
}
}
private void ctrlToMove_MouseUp(object sender, MouseEventArgs e)
{
_Offset = Point.Empty;
}
private void ctrlToMove_MouseMove(object sender, MouseEventArgs e)
{
if (_Offset != Point.Empty)
{
Point newlocation = ctrlToMove.Location;
newlocation.X += e.X - _Offset.X;
newlocation.Y += e.Y - _Offset.Y;
ctrlToMove.Location = newlocation;
}
}

Drag and Drop position? How to use rectangle? WinForms, C#

Drag and Drop in winform returns the dropped on top-leftmost on its Drop. Or to make it clear, it drops where the cursor of the mouse is. I know I have to add some of the codes like the rectangle. But im new in this drag and drop function. Can someone help me pls? Here's my code:
private void label1_MouseDown(object sender, MouseEventArgs e)
{
label1.DoDragDrop(label1, DragDropEffects.Move);
}
private void panel1_DragDrop(object sender, DragEventArgs e)
{
label1.Location = this.panel1.PointToClient(new Point(e.X, e.Y));
}
private void panel1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
It's at the top left because label1.Location = this.panel1.PointToClient(new Point(e.X, e.Y)); sets the position of the top left. Try getting the location of the mouse relative to the dragged item and subtracting those coordinates.
private void panel1_DragDrop(object sender, DragEventArgs e)
{
//Gives you the position of the mouse relative to the top left of panel1
point offset = e.GetPosition(panel1);
label1.Location = this.panel1.PointToClient(new Point(e.X-offset.X, e.Y-offset.Y));
}

Moving a control within another control's visible area

I have a PictureBox that is inside a TabPage, and of course this TabPage is part of a TabView and this TabView is inside a Form. I want users be able to move this picture box within the tab page. For this I am using the MouseDown, MouseMove and MouseUp events of the picture box:
private void pictureBoxPackageView_MouseDown(object sender, MouseEventArgs e)
{
if (!_mapPackageIsMoving)
{
_mapPackageIsMoving = true;
}
}
private void pictureBoxPackageView_MouseMove(object sender, MouseEventArgs e)
{
if(_mapPackageIsMoving)
{
pictureBoxPackageView.Location = MousePosition; //This is not exact at all!
return;
}
//Some other code for some other stuff when picturebox is not moving...
}
private void pictureBoxPackageView_MouseUp(object sender, MouseEventArgs e)
{
if (_mapPackageIsMoving)
{
_mapPackageIsMoving = false; //Mouse button is up, end moving!
return;
}
}
But my problem lies in the MouseMove event. As soon as I move mouse after button down, the picture box jumps out of tab page's visible area.
I need to know how to handle the move only within the rectangle of the tab page, and if picture box is being dragged out of tab view's visible area, it shouldn't move anymore unless user brings the mouse inside the tab view's visible rectangle.
Any helps/tips will be appriciated!
You need a variable to hold the original position of the PictureBox:
Modified from a HansPassant answer:
private Point start = Point.Empty;
void pictureBoxPackageView_MouseUp(object sender, MouseEventArgs e) {
_mapPackageIsMoving = false;
}
void pictureBoxPackageView_MouseMove(object sender, MouseEventArgs e) {
if (_mapPackageIsMoving) {
pictureBoxPackageView.Location = new Point(
pictureBoxPackageView.Left + (e.X - start.X),
pictureBoxPackageView.Top + (e.Y - start.Y));
}
}
void pictureBoxPackageView_MouseDown(object sender, MouseEventArgs e) {
start = e.Location;
_mapPackageIsMoving = true;
}

Categories

Resources