I need to run code when I dismiss(end) dragging click. How this event is called?
Here is main example, please find the below screenshot for more information:
I made that I can drag the car on other picture boxes like below this:
Repeat again - I need to know what EVENT is then you dismiss to drag on picture box?
There is no event for when the drag is released on a control, but you don't really need one. This is what I did to simulate what (I think) you're looking for. I used code courtesy of this stackoverflow answer
private Point? _mouseLocation;
private void Form1_Load(object sender, EventArgs e)
{
this.pictureBox1.MouseDown += this.pictureBox1_MouseDown;
this.pictureBox1.MouseUp += this.pictureBox1_MouseUp;
this.pictureBox1.MouseMove += this.pictureBox1_MouseMove;
}
void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if ( this._mouseLocation.HasValue)
{
this.pictureBox1.Left = e.X + this.pictureBox1.Left - this._mouseLocation.Value.X;
this.pictureBox1.Top = e.Y + this.pictureBox1.Top - this._mouseLocation.Value.Y;
}
}
void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
this._mouseLocation = null;
}
void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
//Check if you've left-clicked if you want
this._mouseLocation = e.Location;
}
Setting the mouse location to null with this._mouseLocation = null; is your "drag released" code.
I guess you talking about DragDrop. You can find example here: How to: Enable Drag-and-Drop Operations with the Windows Forms RichTextBox Control
Related
This question already has answers here:
Why doesn't doubleclick event fire after mouseDown event on same element fires?
(2 answers)
Closed 5 years ago.
I have a MenuStrip from which I want to drag some things on the form body(then some things happen such as the backcolor of the form is changing, etc). I am handling the MouseDown event, but the thing is that when I click on the option in the ToolStripMenu the same things happen(the backcolor of the form is changing, etc).
What I want is to somehow separate the MouseClick from the MouseDown. More precisely, when I click on one option of the MenuStrip I don't want anything to happen.
When I click, the MouseDown event fires. I want to ignore it unless the mouse's cursor moves.
private void salmonToolStripMenuItem_MouseDown(object sender, MouseEventArgs e)
{
//gets the cursor position at the moment when mouse down is activated
p1M = Cursor.Position.X;
p2M = Cursor.Position.Y;
//miscare shows if the mouse moved
if (miscare == true)
{
//do things
}
}
private void Rezervare1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
private void salmonToolStripMenuItem_MouseUp(object sender, MouseEventArgs e)
{
//gets the cursor position to see if it moved
p1m = Cursor.Position.X;
p2m = Cursor.Position.Y;
if (p1M != p1m || p2M != p2m)
{
miscare = true;//it means the cursor moved
}
else miscare = false;
}
If you want your logic to happen on mouse move, then lets handle MouseMove!
bool isMouseDown = false;
private void salmonToolStripMenuItem_MouseDown(object sender, MouseEventArgs e)
{
isMouseDown = true;
}
private void salmonToolStripMenuItem_MouseUp(object sender, MouseEventArgs e)
{
isMouseDown = false;
}
private void salmonToolStripMenuItem_MouseMove(object sender, MouseEventArgs e)
{
if(isMouseDown)
{
//Do your thing
}
}
Also note, there are some strange edge cases you can hit with things like the form losing focus, or the user dragging outside of the bounds of the form. Something to be aware of and handle as needed.
I know from this question how to handle a drag&Drop
https://stackoverflow.com/a/17872857/982161
but I can not detect when the Drag event begins so I can prepare some resources...
if I print those events the Drop is coming first and after that the Drag..
how can this be cleanly handled
My Code is pretty simple
private void Label_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var lbl = (Label)sender;
DragDrop.DoDragDrop(lbl, lbl.Content, DragDropEffects.Move);
Console.WriteLine("Drag...");
}
private void Label_Drop(object sender, DragEventArgs e)
{
Console.WriteLine("Drop...");
}
private void Label_DragEnter(object sender, DragEventArgs e)
{
Console.WriteLine("Label_DragEnter...");
}
private void Label_DragLeave(object sender, DragEventArgs e)
{
Console.WriteLine("Label_DragLeave...");
}
Long story short: If you want to prepare resources before you drop the label, write that code before calling the DragDrop method or in the OnPreviewMouseDown event.
Long Story:
Using Snoop I was able to look into the events that are triggering when dragging the label.
It appears that the only events triggering are the PreviewMouseDown and MouseDown.
So we should only implement those events.
private void Lbl_OnMouseDown(object sender, MouseButtonEventArgs e)
{
var lbl = (Label)sender;
DragDrop.DoDragDrop(lbl, lbl.Content, DragDropEffects.Move);
Console.WriteLine("Drag...");
}
private void UIElement_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("Label_PreviewMouseDown...");
}
This will result in first printing "Label_PreviewMouseDown..." when starting to drag the label and "Drag..." when the label is done being dragged.
However, this isn't the complete truth.
Let's modify our code a little. Let's add DateTime.Now.Second to test when the messages are actually triggering. I will then drag the label for a few seconds, then drop it to see the order of printing to console.
private void Lbl_OnMouseDown(object sender, MouseButtonEventArgs e)
{
var lbl = (Label)sender;
Console.WriteLine("Label_OnMouseDown_BeforeDragging..." + DateTime.Now.Second);
DragDrop.DoDragDrop(lbl, lbl.Content, DragDropEffects.Move);
Console.WriteLine("Label_OnMouseDown_AfterDragging..." + DateTime.Now.Second);
}
private void UIElement_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("Label_PreviewMouseDown..." + DateTime.Now.Second);
}
Now let's try dragging again.
Turns out that OnMouseDown happens before you are done dragging. The DoDragDrop method pauses the code there until you drop the label, then you are able to continue and print to the console.
So therefore: If you want to prepare resources before you drop the label, write that code before calling the DragDrop method or in the OnPreviewMouseDown event.
Hope this helps.
If you need a drag event that is not provided by the control then you may consider adding one to your own code. For example
// Event fired immediately before DragDrop
public DragEventHandler DragBegin { get; set; }
private void Label_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var lbl = (Label)sender;
// Create args object and fire event if not null
var args = new DragEventArgs(new DataObject(lbl.Content), DragDropKeyStates.None, DragDropEffects.None, lbl, e.GetPoint(lbl));
DragBegin?.Invoke(sender, args);
DragDrop.DoDragDrop(lbl, lbl.Content, DragDropEffects.Move);
Console.WriteLine("Drag...");
}
You could then bind to that event from anywhere you have a reference to that code behind, such as
MyUserControl.DragBegin += (sender, args) => /* some behavior */;
I have a program that uses OpenTk.GLControl. Now on my listener, every time the mouse hovers to the said control, say "glControl1", I want to get the mouse coordinates.
Is that possible? sample code below.
private void glControl1_MouseHover(object sender, EventArgs e)
{
// get the current mouse coordinates
// .........
}
OpenTK.GLControl inherits from System.Windows.Forms.Control. You can use the following code snippet to get the mouse position:
private void glControl1_MouseHover(object sender, EventArgs e)
{
Control control = sender as Control;
Point pt = control.PointToClient(Control.MousePosition);
}
Please refer to the MSDN WinForms documentation for more information.
The problem is that you're using the wrong event. Many UI actions in WinForms trigger multiple events per action; Hover is used for things like popping up tooltips. You don't get a coordinate in Hover because it's unnecessary.
What you want is the MouseMove event. This is used to track the mouse position:
private void glControl1_MouseMove(object sender, MouseEventArgs e)
{
foo = e.X;
bar = e.Y;
}
I dont know, what is OpenTk.GLControl, but:
I was handling swipe events on Windows Phone and did this:
private void PhoneApplicationPage_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
//string to save coordinates of tap
TapCoordinatesXBegin = e.GetPosition(LayoutRoot).X.ToString();
TapCoordinatesYBegin = e.GetPosition(LayoutRoot).Y.ToString();
}
And i dont remember such event MouseHover - maybe MouseEnter?
I have a button on my WinForms app that I want to be invisible until the user moves his mouse over the button. Then they could click it. If the mouse leaves the button, it needs to be hidden again. The button.Visible parameter makes the button completely inaccessible and disables the mouse over. Any ideas or other button parameters I could use?
This currently does not work:
private void settingButton_MouseEnter(object sender, EventArgs e)
{
settingButton.Visible = true;
}
private void settingButton_MouseLeave(object sender, EventArgs e)
{
settingButton.Visible = false;
}
This issue was brought up and answered here:
C# WinForms MouseHover and MouseLeave problem
private void Form_MouseMove(object sender, MouseEventArgs e) {
if(settingButton.Bounds.Contains(e.Location) && !settingButton.Visible) {
settingButton.Show();
}
}
I am working on a project. It does with drag and drop this is the code I have right now.
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
listBox1.DoDragDrop(listBox1.SelectedItem.ToString(), DragDropEffects.Move);
}
private void listBox2_DragEnter(object sender, DragEventArgs e)
{
e.Effect = e.AllowedEffect;
}
private void listBox2_DragDrop(object sender, DragEventArgs e)
{
listBox2.Items.Add(e.Data.GetData(DataFormats.Text));
listBox1.Items.Remove(listBox1.SelectedItem.ToString());
}
It lets you add to the second list box but I am trying to get it where you can also move the item back to first listbox if you want to. Do I repeat the code for the second list box as I did for the first one or is there a line of code I could just add.Also how can you tell if your program is “unbreakable”. Thanks.
Do I repeat the code for the second list box
Pretty much, yeah. Although you can simplify it a bit since the code will be essentially identical by having both listboxes use the same handler for MouseDown, DragEnter and DragDrop and then use the sender to figure out whether it's listBox1 or listBox2.
Also, you might want to think about your MouseDown handler. Most users won't expect a single click to immediately start a drag operation. Usually you would look for the mouse down and then for a mouse move while the button is down before starting the drag.
What I usually do is something like this:
private Size dragSize = SystemInformation.DragSize;
private Rectangle dragBounds = Rectangle.Empty;
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
dragBounds = new Rectangle(new Point(e.X - dragSize.Width / 2, e.Y - dragSize.Height/2), dragSize);
}
else
{
dragBounds = Rectangle.Empty;
}
}
private void listBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && dragBounds != Rectangle.Empty && !dragBounds.Contains(e.X, e.Y))
{
//start drag
listBox1.DoDragDrop(listBox1.SelectedItem.ToString(), DragDropEffects.Move);
dragBounds = Rectangle.Empty;
}
}
For the main question of implementing drag & drop: yes, you would need to create handlers for listbox1 and listbox2 that mirror the functionality you already have:
A MouseDown event handler for listBox2
A DragEnter handler for listBox1
A DragDrop handler for listBox1.
Also you'd need to make sure you assign these handlers to be used for their respective events in the form designer.
You could reapeat the code, but I tend to not want to do that. Yours is an edge case; lots of methods that only have one line in them. But any time I see repetition in code, it signals to me that I need to pull that code out somewhere else. If the repetition is in the same class, move it to its own method on the class. If the repetition is in separate classes, either find another class outside the two where it makes sense to put the new method, or consider creating a new class that both classes can share. In your case, if I decided to move the code, I would do something like this:
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
HandleMouseDown(listbox1);
}
private void listBox2_DragEnter(object sender, DragEventArgs e)
{
HandleDragEnter( e );
}
private void listBox2_DragDrop(object sender, DragEventArgs e)
{
HandleDragDrop( listBox1, listBox2, e );
}
private void listBox2_MouseDown(object sender, MouseEventArgs e)
{
HandleMouseDown(listBox2);
}
private void listBox1_DragEnter(object sender, DragEventArgs e)
{
HandleDragEnter( e );
}
private void listBox1_DragDrop(object sender, DragEventArgs e)
{
HandleDragDrop( listBox2, listBox1, e );
}
private void HandleMouseDown( ListBox listBox )
{
listBox.DoDragDrop(listBox.SelectedItem.ToString(), DragDropEffects.Move);
}
private void HandleDragEnter( DragEventArgs e )
{
e.Effect = e.AllowedEffect;
}
private void HandleDragDrop( ListBox src, ListBox dst, DragEventArgs e )
{
dst.Items.Add( e.Data.GetData(DataFormats.Text) );
src.Items.Remove( src.SelectedItem.ToString() );
}
The advantage to moving the code is, if those methods grow to more than one line, you can change them in only one place. Of course, for a one line method, I would also remember that I can always move it to its own method later. My personal preference would be to leave the two one-line methods as-is, doing a copy & paste for the second listbox, and splitting out the DragDrop handler into its own method like I did above.