I'm trying to make draggable window form, but when I tried to detect mouse down and up event to form, but event does not fire.
Other things seems working but those 2 events are not.
public form()
{
InitializeComponent();
this.BackColor = Color.Fuchsia;
this.TransparencyKey = this.BackColor;
Debug.Write("initialized");
}
private void form_MouseDown(object sender, MouseEventArgs e)
{
Debug.Write("dragging..");
}
private void form_MouseUp(object sender, MouseEventArgs e)
{
Debug.Write("drag done");
}
it is better to add a panel to your form and set Dock to top in order to cover the title bar area. then use this sample code
private bool isDragging = false;
private Point lastLocation;
private void panel_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
lastLocation = e.Location;
}
private void panel_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
this.Location = new Point(
(this.Location.X - lastLocation.X) + e.X,
(this.Location.Y - lastLocation.Y) + e.Y);
this.Update();
}
}
private void panel_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
don't forget to add handlers in the form constructor
panel.MouseDown += panel_MouseDown;
panel.MouseMove += panel_MouseMove;
panel.MouseUp += panel_MouseUp;
In your constructor for form, register those methods your using to listen for the mouse down events like this.
public form() {
InitializeComponent();
this.BackColor = Color.Fuchsia;
this.TransparencyKey = this.BackColor;
Debug.Write("initialized");
//register the methods to listen for the events
this.MouseDown += form_MouseDown;
this.MouseUp += form_MouseUp;
}
private void form_MouseDown(object sender,
MouseEventArgs e) {
Debug.Write("dragging..");
}
private void form_MouseUp(object sender,
MouseEventArgs e) {
Debug.Write("drag done");
}
Related
I was trying to set up a system to check if the mouse is clicked in a winforms application and have ended up doing this
private void lblChips_MouseDown(object sender, MouseEventArgs e)
{
mouseDown = true;
}
private void lblChips_MouseUp(object sender, MouseEventArgs e)
{
mouseDown = false;
}
eight times over (for each label).
Does anyone know if there's a more efficient way of doing this? I tried using
private void frmGame4_MouseDown(object sender, MouseEventArgs e)
{
mouseDown = true;
}
private void frmGame4_MouseUp(object sender, MouseEventArgs e)
{
mouseDown = false;
}
but that doesnt work. Any help would be greatly appreciated.
this
public Form1()
{
InitializeComponent();
CollectFormControls(this);
ControlList.Add(this);
MergeEvents();
}
List<Control> ControlList = new List<Control>();
private void CollectFormControls(Control c)
{
foreach (Control control in c.Controls)
{
ControlList.Add(control);
CheckSubControls(control);
}
}
private void CheckSubControls(Control control)
{
if (control.Controls.Count > -1)
{
CollectFormControls(control);
}
}
private void MergeEvents()
{
for (int i = 0; i < ControlList.Count; i++)
{
ControlList[i].MouseDown += All_MouseDown;
ControlList[i].MouseUp += All_MouseUp;
}
}
public void All_MouseUp(object sender, MouseEventArgs e)
{
this.Text = "up";
}
public void All_MouseDown(object sender, MouseEventArgs e)
{
this.Text = "down";
}
You could make two methods, one for mouse up and one for mouse down, like this:
private void labels_mouseDown(object sender, MouseEventArgs e)
{
mouseDown = true;
}
private void labels_mouseUp(object sender, MouseEventArgs e)
{
mouseDown = false;
}
Then, link all the labels to these methods. You can also do this from Code:
label.mouseDown += labels_mouseDown;
label.mouseUp += labels_mouseUp;
This has to be done somewhere under the InitializeComponent(); method. You still have to do this for every label but in the end it's less code.
I have created a winform application for school project. But in certain situation I want to let user to move the form only vertically by dragging the form.
So, I have tried this.
private bool dragging = false;
private Point pointClicked;
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (dragging)
{
Point pointMoveTo;
pointMoveTo = this.PointToScreen(new Point(e.Y,e.Y));
pointMoveTo.Offset(-pointClicked.X, -pointClicked.Y);
this.Location = pointMoveTo;
}
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
dragging = true;
pointClicked = new Point(e.X, e.Y);
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
dragging = false;
}
But it doesn't seem to work. It moves the form across the screen. So, is there a way to restrict form movement to vertical?
You should not set this.Location, but only the this.Location.Y value:
this.Location = pointToMoveTo;
should become
this.Top = pointToMoveTo.Y;
Your original code changed both the X and Y coordinates, effectively doing a diagonal move.
Try something like this:
public partial class Form1 : Form
{
private bool dragging = false;
private int pointClickedY;
public Form1() {
InitializeComponent();
}
private void Form1_MouseDown(object sender, MouseEventArgs e) {
dragging = true;
pointClickedY = e.Y;
}
private void Form1_MouseUp(object sender, MouseEventArgs e) {
dragging = false;
}
private void Form1_MouseMove(object sender, MouseEventArgs e) {
if (dragging) {
int pointMoveToY = e.Y;
int delta = pointMoveToY - pointClickedY;
Location = new Point(Location.X, Location.Y + delta);
}
}
}
I am using MousePosition to try to determine which way the user moves his or her mouse after the MouseDown event is triggered. The problem is I am trying to make a starting variable using Point datatype and I only want this Point to be filled with data once but I have it in a MouseDown so I can use the mouse arguments e.X and e.Y to determine where the MouseDown event was called. Here is an example of what im thinking of
public void panel1_MouseDown(object sender, MouseEventArgs e)
{
Point start = new Point(e.X, e.Y);
}
public void panel1_MouseMove(object sender, MouseEventArgs e)
{
if(MousePosition.X > start.X)
{
Console.WriteLine("you have moved right");
}
}
so how would I only create that start variable once while still having it have access to the e mouse argument. and also how would I access the variable between panel1_MouseDown and panel1_MouseMove? If you see a better alternative to doing this too that would be great! Thank you all for the help!
If you have aversion to define new class members (for some reason), this is the least you could have:
Point? start = null;
public void panel1_MouseDown(object sender, MouseEventArgs e)
{
start = new Point(e.X, e.Y);
}
public void panel1_MouseUp(object sender, MouseEventArgs e)
{
start = null;
}
public void panel1_MouseMove(object sender, MouseEventArgs e)
{
if(start.HasValue)
if(MousePosition.X > start.Value.X)
Console.WriteLine("you have moved right");
}
But for clarity (and functionality) I'd have an additional boolean variable:
bool mouseIsDown = false;
Point start;
public void panel1_MouseDown(object sender, MouseEventArgs e)
{
start = new Point(e.X, e.Y);
mouseIsDown = true;
}
public void panel1_MouseUp(object sender, MouseEventArgs e)
{
mouseIsDown = false;
}
public void panel1_MouseMove(object sender, MouseEventArgs e)
{
if(mouseIsDown)
if(MousePosition.X > start.X)
Console.WriteLine("you have moved right");
}
declare your start point as private class variable
Private Point start;
public void panel1_MouseDown(object sender, MouseEventArgs e)
{
this.start = new Point(e.X, e.Y);
}
public void panel1_MouseMove(object sender, MouseEventArgs e)
{
if(MousePosition.X > this.start.X)
{
Console.WriteLine("you have moved right");
}
}
I want my application to hide when the user want to close it.
after that by clicking on notifyicon the form will be shown .
Here is my coded : [form name = login]
private void login_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
this.hide();
}
and for notifyicon :
private void NIcon_MouseClick(object sender, MouseEventArgs e)
{
this.Show();
}
but it doesn't work! What is wrong?
You can try also ShowInTaskbar property
private void LoginForm_FormClosing(object sender, FormClosingEventArgs e)
{
Hide();
e.Cancel = true;
ShowInTaskbar = false;
}
private void LoginForm_DoubleClick(object sender, EventArgs e)
{
ShowInTaskbar = true;
Show();
}
You have to add them to the event handlers also, try this on form_load
this.FormClosing += LoginForm_FormClosing;
notifyIcon1.DoubleClick += LoginForm_DoubleClick;
Then you can do like this
login form;
private void LoginForm_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
form.hide();
}
private void LoginForm_DoubleClick(object sender, EventArgs e)
{
form.Show();
}
Also read this it will be helpful.
Please note I'm trying to do the following, when I hover the mouse on a button I want the panel to be visible, when the mouse leaves the button or panel, the panel should not be visible. Below you can see the code I have, but the panel it's not staying visible.
private void FormMain()
{
buttonMenu.MouseEnter += new EventHandler(buttonMenu_MouseEnter); //open panel
buttonMenu.MouseLeave += new EventHandler(buttonMenu_MouseLeave);
panelMenu.MouseEnter += new EventHandler(panelMenu_MouseEnter);
panelMenu.MouseLeave += new EventHandler(panelMenu_MouseLeave);
mbB1.MouseEnter += new EventHandler(mbB1_MouseEnter);//button in panel
mbB2.MouseEnter += new EventHandler(mbB2_MouseEnter);//button in panel
}
private void buttonMenu_MouseEnter(object sender, EventArgs e)
{
this.panelMenu.Visible = true;
}
private void buttonMenu_MouseLeave(object sender, EventArgs e)
{
this.panelMenu.Visible = false;
}
private void panelMenu_MouseEnter(object sender, EventArgs e)
{
this.panelMenu.Visible = true;
}
private void panelMenu_MouseLeave(object sender, EventArgs e)
{
this.panelMenu.Visible = false;
}
private void mbB1_MouseEnter(object sender, EventArgs e)
{
this.panelMenu.Visible = true;
}
private void mbB2_MouseEnter(object sender, EventArgs e)
{
this.panelMenu.Visible = true;
}
One solution that came to my mind is using a short timer. You may further optimize it to cut down on LoC, but it works. You may also lower the timer's delay, but 100ms is what I think would be a safe one.
On a side note, I don't think this is a good design. If you want this kind of behaviour, you should either use a ContextMenuStrip or a Click event on the button, and a hide event on panelMenu.MouseLeave. Still, if it's what you really need, this is how I solved it:
public partial class Form1 : Form
{
private bool mouseInPanel;
private Timer hideTimer;
public Form1()
{
InitializeComponent();
buttonMenu.MouseEnter += new EventHandler(button_MouseEnter);
buttonMenu.MouseLeave += new EventHandler(button_MouseLeave);
mbB1.MouseEnter += panelButton_MouseEnter;
mbB2.MouseEnter += panelButton_MouseEnter;
panelMenu.MouseEnter += new EventHandler(panelMenu_MouseEnter);
panelMenu.MouseLeave += new EventHandler(panelMenu_MouseLeave);
hideTimer = new Timer {Interval = 100};
hideTimer.Tick += hidePanel;
}
private void button_MouseEnter(object sender, EventArgs e)
{
this.panelMenu.Visible = true;
}
private void button_MouseLeave(object sender, EventArgs e)
{
hideTimer.Start();
}
private void panelMenu_MouseEnter(object sender, EventArgs e)
{
mouseInPanel = true;
this.panelMenu.Visible = true;
}
private void panelMenu_MouseLeave(object sender, EventArgs e)
{
mouseInPanel = false;
hideTimer.Start();
}
private void panelButton_MouseEnter(object sender, EventArgs e)
{
mouseInPanel = true;
this.panelMenu.Visible = true;
}
private void hidePanel(object sender, EventArgs e)
{
hideTimer.Stop();
if (!mouseInPanel) this.panelMenu.Visible = false;
}
}
What I figured is your mouse actions needed a little bit of a delay, else the panel (along with your buttons mbB1 and mbB2) gets hidden before those buttons' actions could be triggered.
This is because by entering the panel buttons you leave the panel, and it disappears (along with it's capability to receive mouse actions) right before mbB1/mbB2's action can trigger.