I am trying to make my Form, which has no border, moveable with holding the left mousebutton down and exit the while loop, when releasing the mousebutton.
But the code I have right now doesn't exit the loop on release.
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
mouseDown = true;
while (mouseDown)
{
mouseX = MousePosition.X;
mouseY = MousePosition.Y - 30;
this.SetDesktopLocation(mouseX, mouseY);
if (e.Button != MouseButtons.Left)
mouseDown = false;
}
I also tried to add a mouseUp event but it cant happen as long as mouseDown is active.
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
mouseDown = true;
}
OK, I fixed it for myself.
I just did this:
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
mouseDown = true;
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
mouseDown = false;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (mouseDown)
{
mouseX = MousePosition.X - 20;
mouseY = MousePosition.Y - 40;
this.SetDesktopLocation(mouseX, mouseY);
}
}
By using a loop in the on mouse up event you are locking the thread. You could use the MouseMove event with a public variable to check if the mouse is down.
Related
I am trying to start a drag and drop on a Button control in WPF. I am using Button because I also want to handle click event.
Adding a Button in XAML and handling the MouseMove event always has e.LeftMouse equal to MouseButtonState.Released.
<Button MouseMove="Button_MouseMove"/>
In the following handler implementation the exception is never thrown.
private void Button_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
throw new Exception("It works!");
}
I noticed the same is true for any control I place inside a Button and try to process MouseMove event.
How do I handle drag and drop from a Button control or any other control inside a button in WPF?
EDIT - Solution based on mm8's answer
The updated XAML is:
<Button PreviewMouseDown="Button_PreviewMouseDown"
PreviewMouseUp="Button_PreviewMouseUp"
PreviewMouseMove="Button_PreviewMouseMove">
</Button>
The updated handler code:
Point startPosition;
double delta = 10;
private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
startPosition = e.GetPosition(this);
}
private void Button_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
Point currentPosition = e.GetPosition(this);
if ((currentPosition - startPosition).Length < delta)
throw new Exception("MouseClick");
}
private void Button_PreviewMouseMove(object sender, MouseEventArgs e)
{
Point currentPosition = e.GetPosition(this);
double currentDelta = (currentPosition - startPosition).Length;
if (e.LeftButton == MouseButtonState.Pressed && currentDelta >= delta)
throw new Exception("DragAndDrop");
}
You could perhaps handle the PreviewMouseDown event instead of Click:
private void Button_Click(object sender, MouseButtonEventArgs e)
{
//handle click here...
e.Handled = true;
}
XAML:
<Button PreviewMouseDown="Button_Click" MouseMove="Button_MouseMove"/>
I am a beginner programmer and I feel like I am repeating code unnecessarily. I want to make a picture puzzle game consisting of 16 pictureboxes. The problem is that I feel like I have to repeat code for each picturebox's events as in the below example:
Point move;
bool isDragging = false;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
move = e.Location;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if(isDragging == true)
{
pictureBox1.Left += e.X - move.X;
pictureBox1.Top += e.Y - move.Y;
pictureBox1.BringToFront();
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
Just create one method for each of your 3 events:
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
move = e.Location;
}
private void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
if(isDragging == true)
{
// Luckily the sender parameter will tell us which PictureBox we are dealing with
PictureBox pb = (PictureBox)sender;
pb.Left += e.X - move.X;
pb.Top += e.Y - move.Y;
pb.BringToFront();
}
}
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
Then go to each of your 16 picture boxes in the designer and set the MouseUp event handler to point to pictureBox_MouseUp and the MouseMove event handler to point to pictureBox_MouseMove and the MouseDown event handler to point to pictureBox_MouseMove. Do this for each of the 16 picture boxes.
Try to trigger same events for all PictureBox Controls
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
move = e.Location;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
PictureBox pictureBox = sender as PictureBox;
if(isDragging == true)
{
pictureBox .Left += e.X - move.X;
pictureBox .Top += e.Y - move.Y;
pictureBox .BringToFront();
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
Create a new component contained Image component and set dock parent container. Write your drag drop codes into the new component.
For example,
public partial class DraggablePictureBox : UserControl
{
public DraggablePictureBox()
{
InitializeComponent();
}
/// <summary>
/// Sets image of inner picture
/// </summary>
public Image Image
{
get {
return InnerPictureBox.Image;
}
set
{
InnerPictureBox.Image = value;
}
}
private void InnerPictureBox_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging == true)
{
this.Left += e.X - move.X;
this.Top += e.Y - move.Y;
this.BringToFront();
}
}
private void InnerPictureBox_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
private void InnerPictureBox_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
move = e.Location;
}
private Point move;
private bool isDragging = false;
}
Now you have a one drag drop code for images.
One way to combat this would be to put these in methods, for example
MovePicturePox(Point move, Point newPos, PictureBox pb)
{
pb.Left += newPos.X - move.X;
pb.Top += newPos.Y - move.Y;
pb.BringToFront();
}
These methods can then be called like so
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if(isDragging == true)
{
MovePictureBox(move, new Point(e.X, y.Y), pictureBox1);
}
}
I am having trouble with painting usercontrol on form while moving the control.
The background of the control is shortened if moved to the right or downwards.
My control
public class DotPanel : Control
{
public DotPanel()
{
this.DoubleBuffered = true;
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.FillRectangle(new SolidBrush(Color.Yellow),new Rectangle(this.Location,this.Size));
}
}
The main form just places the usercontrol on specified location and supplies the mouse down/move/up events to do the moving
Basicaly this>>
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
mouseX = e.X;
mouseY = e.Y;
panelX = dp1.Left;
panelY = dp1.Top;
moving = true;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (moving)
{
dp1.Left = panelX + e.X - mouseX;
dp1.Top = panelY + e.Y - mouseY;
this.Invalidate(true);
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
moving = false;
this.Invalidate(true);
}
Thanks in advance for any clues...
the overriden paint was the problem.
exchanging this.Size and this.Location for ClientRectangle.Size and ClientRectangle.Location worked...
I have a card game application, and I want to create a simple animation that will make the button move when it is clicked and dragged.
I have tried:
bool _Down = false;
private void button1_MouseDown(object sender, MouseEventArgs e)
{
_Down = true;
}
private void button1_MouseUp(object sender, MouseEventArgs e)
{
_Down = false;
button1.Location = e.Location;
}
private void button1_MouseMove(object sender, MouseEventArgs e)
{
if (_Down)
{
button1.Location = e.Location;
}
}
This doesn't work either. The effect I get is that when the button is clicked and dragged, the button is not visible until the mouse is released, and also, the button doesn't actually stay at the location of the mouse.
I also tried:
bool _Down = false;
private void button1_MouseDown(object sender, MouseEventArgs e)
{
_Down = true;
}
private void button1_MouseUp(object sender, MouseEventArgs e)
{
_Down = false;
button1.Location = Cursor.Position;
}
private void button1_MouseMove(object sender, MouseEventArgs e)
{
if (_Down)
{
button1.Location = Cursor.Position;
}
}
This works better than the first one as the button is visible when dragged and stops at mouse position, but the only problem is that Cursor.Position returns the cursor position in relativeness to the screen, not the form therefore. The button doesn't actually move at the pace of the cursor.
What can I do to achieve what I want?
Moving Control at runtime is very easy:
Point downPoint;
private void button1_MouseDown(object sender, MouseEventArgs e)
{
downPoint = e.Location;
}
private void button1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) {
button1.Left += e.X - downPoint.X;
button1.Top += e.Y - downPoint.Y;
}
}
Try this
private void button1_MouseUp(object sender, MouseEventArgs e)
{
_Down = false;
button1.Location = PointToClient(Cursor.Position);
}
private void button1_MouseMove(object sender, MouseEventArgs e)
{
if (_Down)
{
button1.Location = PointToClient( Cursor.Position);
}
}
we able to move windows forms when we mouse down on title bar .
but how can I move windows when mouse down in form ?
You'll need to record when the mouse is down and up using the MouseDown and MouseUp events:
private bool mouseIsDown = false;
private Point firstPoint;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
firstPoint = e.Location;
mouseIsDown = true;
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
mouseIsDown = false;
}
As you can see, the first point is being recorded, so you can then use the MouseMove event as follows:
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (mouseIsDown)
{
// Get the difference between the two points
int xDiff = firstPoint.X - e.Location.X;
int yDiff = firstPoint.Y - e.Location.Y;
// Set the new point
int x = this.Location.X - xDiff;
int y = this.Location.Y - yDiff;
this.Location = new Point(x, y);
}
}
You can do it manually by handling the MouseDown event, as explained in other answers. Another option is to use this small utility class I wrote some time ago. It allows you to make the window "movable" automatically, without a line of code.
Listen for the event when the mouse button goes down in the form and then listen for mouse moves until it goes up again.
Here's a codeproject article that shows how to do this: Move window/form without Titlebar in C#
You can't use location provided in MouseUp or Down, you should use system location like this
private Point diffPoint;
bool mouseDown = false;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
//saves position difference
diffPoint.X = System.Windows.Forms.Cursor.Position.X - this.Left;
diffPoint.Y = System.Windows.Forms.Cursor.Position.Y - this.Top;
mouseDown = true;
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
mouseDown = false;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (mouseDown)
{
this.Left = System.Windows.Forms.Cursor.Position.X - diffPoint.X;
this.Top = System.Windows.Forms.Cursor.Position.Y - diffPoint.Y;
}
}
This works, tested.