Change WinForms Button Style upon mousedown and leave - c#

How can I change a button's style, in particular the image, upon the mouse being pressed and held and then the cursor dragged away from the button?
You'll notice that, on this action, the default behaviour for the button is to revert it's style to hover style. This can be partially configured using the MouseOverBackColor. I want to ensure that, whenever the MouseOverBackColor is applied, I also have a specific image on the button.
I have tried the code below, to have an "isMouseDown" flag which is checked in the leave event. However, this doesn't work for me.
private void btnFormMinimize_MouseClick(object sender, MouseEventArgs e)
{
this.WindowState = FormWindowState.Minimized;
}
bool isMouseDown = false;
private void btnFormMinimize_MouseDown(object sender, MouseEventArgs e)
{
Button b = (Button)sender;
b.Image = Properties.Resources.icon_minimize_click;
isMouseDown = true;
}
private void btnFormMinimize_MouseEnter(object sender, EventArgs e)
{
Button b = (Button)sender;
b.Image = Properties.Resources.icon_minimize_hover;
}
private void btnFormMinimize_MouseLeave(object sender, EventArgs e)
{
Button b = (Button)sender;
if (isMouseDown)
{
b.Image = Properties.Resources.icon_minimize_hover;
}
else
{
b.Image = Properties.Resources.icon_minimize;
}
}
private void btnFormMinimize_MouseUp(object sender, MouseEventArgs e)
{
isMouseDown= false;
}
Thanks in advance.

Related

Hide Cursor on being moveless for certain amount of time and show it again on move

I want to hide the cursor after a certain time (if the mouse is not moving), and I want to show the cursor when I move the mouse in a picturebox. I just can't get it to work... This is what I have tried:
// this Never seem to hide the cursor
private void picBox_MouseMove(object sender, MouseEventArgs e)
{
Cursor.Show();
tim.Stop();
tim.Start();
}
private void tim_Tick(object sender, EventArgs e)
{
Cursor.Hide();
tim.Stop();
}
-
// works but in this case I want cursor.ico to be a resource
private void picBox_MouseMove(object sender, MouseEventArgs e)
{
Cursor.Current = Cursors.Default;
tim.Stop();
tim.Start();
}
private void tim_Tick(object sender, EventArgs e)
{
Cursor.Current = new Cursor("cursor.ico");
tim.Stop();
}
-
// Properties.Resources.cursor gives an error even though I added it to my resources
// cannot convert from 'System.Drawing.Icon' to 'System.IntPtr'
private void picBox_MouseMove(object sender, MouseEventArgs e)
{
Cursor.Current = Cursors.Default;
tim.Stop();
tim.Start();
}
private void tim_Tick(object sender, EventArgs e)
{
Cursor.Current = new Cursor(Properties.Resources.cursor);
tim.Stop();
}
You need to have a timer and handle its Tick event. In the Tick event, check if the last movement of the mouse was before the certain time, then hide the cursor using Cursor.Hide(). Also handle MouseMove of the PictureBox and show the cursor using Cursor.Show() method.
Note: Don't forget to enable the timer and set Interval of timer to a short value, for example 300 and change duration value in the following code, for a shorter/longer inactive time:
DateTime? lastMovement;
bool hidden = false;
int duration = 2;
void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
lastMovement = DateTime.Now;
if (hidden)
{
Cursor.Show();
hidden = false;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (!lastMovement.HasValue)
return;
TimeSpan elaped = DateTime.Now - lastMovement.Value;
if (elaped >= TimeSpan.FromSeconds(duration) && !hidden)
{
Cursor.Hide();
hidden = true;
}
}

Click event on button that is draggable?

So, I made a button that is draggable with these events:
bool isMouseClicked;
private void button1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isMouseClicked = true;
}
}
private void button1_MouseMove(object sender, MouseEventArgs e)
{
if (isMouseClicked == true)
//You then set your location of your control. See below:
button1.Location = new Point(MousePosition.X, MousePosition.Y);
}
private void button1_MouseUp(object sender, MouseEventArgs e)
{
isMouseClicked = false;
}
Now, I want to insert something to the "Click" event. When I try to drag the button, the action from the "Click" event is performed. I only want the button to move when I drag it and to perform the action from the "Click" event when I click it. How can I do this?
I would suggest your bool should be named isMouseDown. Now, the Click event fires when a MouseDown and then MouseUp event occurs on the same control. So add another bool justDragged, set it to false on MouseDown, set it to true on MouseMove and isMouseDown and test it in the Click event.
BTW, this information is on SO, just a bit scattered around.
bool isMouseDown = false;
bool justDragged = false;
private void button1_MouseDown(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
isMouseDown = true;
justDragged = false;
}
}
private void button1_MouseMove(object sender, MouseEventArgs e) {
if (isMouseDown) {
//You then set your location of your control. See below:
button1.Location = new Point(MousePosition.X, MousePosition.Y);
justDragged = true;
}
}
private void button1_MouseUp(object sender, MouseEventArgs e) {
isMouseDown = false;
}
private void button1_Click(object sender, MouseEventArgs e) {
if (!justDragged) { // then we clicked
// do click handling
}
}

Double Click on label open Form C#

Im trying to open a new form when a label is double clicked. Im able to drag and drop the label .Im trying to open a new form on double click of label now.
private void control_MouseDown(object sender, MouseEventArgs e)
{
var control = sender as Control;
this.DoDragDrop(control.Name, DragDropEffects.Move);
}
private void control_DoubleClick(object sender, EventArgs e)
{
frm = new Frm();
frm.ShowDialog();
frm.Dispose();
}
EDIT 1:
I have tried both possible answers below, and they have not worked for me?
A more cleaner way is (note I changed Frm to Form1):
private void control_DoubleClick(object sender, EventArgs e)
{
using (Form1 frm = new Form1())
{
frm.ShowDialog();
}
}
You can't add DragDrop on MouseDown and then DoubleClick. That won't work.
I don't think there's an easy way to get around that, but once a control is being dragged, it won't respond to double click messages.
I've made some quick tests, and there's a "hacky" way. It'll make your dragging look weird (since it'll start after some time, instead of immediately after you press the mouse button), but here it goes:
private bool _willDrag = false;
private bool control_MouseUp(object sender, MouseEventArgs e)
{
// disable dragging if we release the mouse button
_willDrag = false;
}
private bool control_DoubleClick(object sender, EventArgs e)
{
// disable dragging also if we double-click
_willDrag = false;
// .. the rest of your doubleclick event ...
}
private void control_MouseDown(object sender, MouseEventArgs e)
{
var control = sender as Control;
if (control == null)
return;
_willDrag = true;
var t = new System.Threading.Timer(s =>
{
var callingControl = s as Control;
if (callingControl == null)
return;
// if we released the mouse button or double-clicked, don't drag
if(!_willDrag)
return;
_willDrag = false;
Action x = () => DoDragDrop(callingControl.Name, DragDropEffects.Move);
if (control.InvokeRequired)
control.Invoke(x);
else
x();
}, control, SystemInformation.DoubleClickTime, Timeout.Infinite);
}
In the form.Designer right click on your label then properties, in the properties window click in events (the thunder icon), in the double_Click event dropdown select the event handler (control_DoubleClick) this method must have two parameters an object and a eventArgs
This is tricky as the DoDragDrop will eat up any further mouse events, and MSDN posting a rather stupid example doesn't help much.
Solution: Do not start the D&D in the MouseDown if you want to still receive click or double click events but use the MouseMove instead:
Replace this
private void control_MouseDown(object sender, MouseEventArgs e)
{
var control = sender as Control;
this.DoDragDrop(control.Name, DragDropEffects.Move);
}
by this:
private void control_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
DoDragDrop((sender as Control), DragDropEffects.Move);
}
Don't forget to hook up the new event!

Make a PictureBox visible / not visible using MouseHover

I think this is a stupid question, but I don't understand what is happening here.
I use this code:
private void pictureBox1_MouseHover(object sender, EventArgs e)
{
pictureBox1.Visible = false;
pictureBox1.BackColor = Color.Black;
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
pictureBox1.Visible = true;
}
The problem is: The picturebox changes color to black if mouse is over picturebox, but the visibility doesn't change. Why?
I think your problem is as soon as you hover the picture it really disappears (that's why you see the back color turn to black, the event is firing). However the picture disappears which lead to situation where your mouse is not on the picture anymore, therefore Mouse_Leave event firing.
You can use MouseEnter event instead of MouseHover and bool field isHover that you can use in attempt to reduce flickering :
public partial class Form1: Form
{
bool isHover = false;
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
if(isHover) return;
// with MouseHover this control visibility appears to be locked with MouseEnter it is not
pictureBox2.Visible = false;
pictureBox2.BackColor = Color.Black;
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
if(!isHover) return;
isHover = false;
pictureBox2.Visible = true;
}
...
}

c# Superposed control doesn't fire events

My Windows Forms code has two superposed PictureBoxes: a small X on the top corner of a user-loaded image. I'll call them DelImage and Image, respectively. Like this:
http://imgur.com/fsW7R8i
The DelImage appears (Visible = true) on Image_MouseEnter and disappears on Image_MouseLeave. Now, I want the DelImage to have a custom behavior as well when the mouse enters it, but DelImage never fires events (nor MouseEnter, nor MouseLeave, nor Click). I've tried bringing it to front, but it already is in front of the Image.
Here's some code:
private void picImage_MouseEnter(object sender, EventArgs e)
{
delImage.Visible = true;
}
private void picImage_MouseLeave(object sender, EventArgs e)
{
delImage.Visible = false;
}
private void picDelImage_MouseEnter(object sender, EventArgs e)
{
delImage.Visible = true;
this.Cursor = Cursors.Hand;
}
private void picDelImage_MouseLeave(object sender, EventArgs e)
{
this.Cursor = Cursors.Arrow;
}
private void picDelImage_Click(object sender, EventArgs e)
{
Panel currentPanel = this.tlpImages.Controls["pnlImage"] as Panel;
currentPanel.Visible = false;
}
With this code, the picDelImage events are never reached. I never enter DelImage, apparently because I never leave Image. What can I do to make my PictureBoxes have the expected behavior?

Categories

Resources