Moving a control in runtime with c#, without using c++ api
-
Hi, I'm trying to move a control while clicking on it. it works but very bad! When i click the control down (panel), and start moving it, it is continuosly swaping between two position and i cant find a reason for that behaviour. This is my code (only the event handlers):
private void panel_MouseDown(object sender, MouseEventArgs e) { Console.WriteLine("mouse down"); Panel region = (Panel)sender; drag = true; } private void panel_MouseUp(object sender, MouseEventArgs e) { Console.WriteLine("mouse up"); drag = false; } private void panel_MouseMove(object sender, MouseEventArgs e) { if (drag) { this.SuspendLayout(); Panel region = (Panel)sender; region.Location = new Point(e.X, e.Y); Console.WriteLine("Panel position: (" + region.Left + "," + region.Top + ")" + "mouse position: (" + e.X + "," + e.Y + ")"); this.ResumeLayout(); } }
Someone has given me an answer to this problem using user32.dll but i want to have more control of the thing. Can anyone help me? Thx Nuno -
Hi, I'm trying to move a control while clicking on it. it works but very bad! When i click the control down (panel), and start moving it, it is continuosly swaping between two position and i cant find a reason for that behaviour. This is my code (only the event handlers):
private void panel_MouseDown(object sender, MouseEventArgs e) { Console.WriteLine("mouse down"); Panel region = (Panel)sender; drag = true; } private void panel_MouseUp(object sender, MouseEventArgs e) { Console.WriteLine("mouse up"); drag = false; } private void panel_MouseMove(object sender, MouseEventArgs e) { if (drag) { this.SuspendLayout(); Panel region = (Panel)sender; region.Location = new Point(e.X, e.Y); Console.WriteLine("Panel position: (" + region.Left + "," + region.Top + ")" + "mouse position: (" + e.X + "," + e.Y + ")"); this.ResumeLayout(); } }
Someone has given me an answer to this problem using user32.dll but i want to have more control of the thing. Can anyone help me? Thx NunoHello, At the MouseDown you have to store the starting point: _startDragPoint = new Point(e.X, e.Y); At the MouseMove I suggest you to use a timer which only changes the Location every 100ms. And add this logic:
if(TimerMovePad == null) { this.TimerMovePad = new System.Timers.Timer(); this.TimerMovePad.Interval = 100; this.TimerMovePad.Elapsed +=new System.Timers.ElapsedEventHandler(TimerMovePad\_Elapsed); } if (TimerMovePad.Enabled == false) { TimerMovePad.Enabled = true; } if(\_movementok == true) { \_movementok = false; int delta\_x = e.X - \_startDragPoint.X; int delta\_y = e.Y - \_startDragPoint.Y; region.Location = new Point((region.Location.X + delta\_x), (region.Location.Y + delta\_y)); }
At the timer Elapsed, you then set the flag.
private void TimerMovePad\_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { TimerMovePad.Enabled = false; \_movementok = true; }
Hope it helps! All the best, Martin
-
Hello, At the MouseDown you have to store the starting point: _startDragPoint = new Point(e.X, e.Y); At the MouseMove I suggest you to use a timer which only changes the Location every 100ms. And add this logic:
if(TimerMovePad == null) { this.TimerMovePad = new System.Timers.Timer(); this.TimerMovePad.Interval = 100; this.TimerMovePad.Elapsed +=new System.Timers.ElapsedEventHandler(TimerMovePad\_Elapsed); } if (TimerMovePad.Enabled == false) { TimerMovePad.Enabled = true; } if(\_movementok == true) { \_movementok = false; int delta\_x = e.X - \_startDragPoint.X; int delta\_y = e.Y - \_startDragPoint.Y; region.Location = new Point((region.Location.X + delta\_x), (region.Location.Y + delta\_y)); }
At the timer Elapsed, you then set the flag.
private void TimerMovePad\_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { TimerMovePad.Enabled = false; \_movementok = true; }
Hope it helps! All the best, Martin
Hi Martin, While i was waiting for an answer i kept trying. I got it! And it was pretty simple! New code:
private void panel_MouseDown(object sender, MouseEventArgs e) { Panel region = (Panel)sender; xi = e.X; yi = e.Y; drag = true; } private void panel_MouseUp(object sender, MouseEventArgs e) { drag = false; } private void panel_MouseMove(object sender, MouseEventArgs e) { if (drag) { Panel region = (Panel)sender; region.Location = new Point((region.Left + (e.X - xi)), (region.Top + (e.Y - yi))); } }
Basicly i think the problem is the diference between the coordinate system from the mouse and control Other thing i dont understand is how does suspend/resume layout works as they weren't doing a thing. Thx anyway, Nuno -
Hi Martin, While i was waiting for an answer i kept trying. I got it! And it was pretty simple! New code:
private void panel_MouseDown(object sender, MouseEventArgs e) { Panel region = (Panel)sender; xi = e.X; yi = e.Y; drag = true; } private void panel_MouseUp(object sender, MouseEventArgs e) { drag = false; } private void panel_MouseMove(object sender, MouseEventArgs e) { if (drag) { Panel region = (Panel)sender; region.Location = new Point((region.Left + (e.X - xi)), (region.Top + (e.Y - yi))); } }
Basicly i think the problem is the diference between the coordinate system from the mouse and control Other thing i dont understand is how does suspend/resume layout works as they weren't doing a thing. Thx anyway, NunoUse the
Capture
property of the control. That makes the control capture all mouse movement, even if you manage move the mouse fast enough to slip outside of the control:private Point start;
private void movable_MouseDown(object sender, MouseEventArgs e) {
Control c = (Control)sender;
start = c.PointToScreen(e.Location);
c.Capture = true;
}private void movable_MouseUp(object sender, MouseEventArgs e) {
Control c = (Control)sender;
c.Capture = false;
}private void movable_MouseMove(object sender, MouseEventArgs e) {
Control c = (Control)sender;
if (c.Capture) {
Point mouse = c.PointToScreen(e.Location);
c.Left += mouse.X - start.X;
c.Top += mouse.Y - start.Y;
start = mouse;
}
}Note: As this code uses the
sender
argument to reference the control, the code can be reused for the events of several controls that you want to be able to move.sinosoidal wrote:
Other thing i dont understand is how does suspend/resume layout works as they weren't doing a thing.
It's used for more complex controls, for example when you want to add a lot of items to a list without having the list redraw itself for every item.
--- single minded; short sighted; long gone;