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.
Related
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");
}
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 coded a form where a panel moves when a button is clicked to the height of the clicked button. However, I want to make the panel move slowly instead of instantly.
This is the code I have used:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
MovePanel(btn1);
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void MovePanel(Control c)
{
Panel.Height = c.Height;
Panel.Top = c.Top;
}
private void btn1_Click(object sender, EventArgs e)
{
MovePanel(btn1);
}
private void btn2_Click(object sender, EventArgs e)
{
MovePanel(btn2);
}
private void btn3_Click(object sender, EventArgs e)
{
MovePanel(btn3);
}
}
I would really like to see a timer-based solution from scratch.
In the meantime, you might check out something like dot-net-transitions, available on NuGet.
using Transitions;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
btn1.Click += btn_Click;
btn2.Click += btn_Click;
btn3.Click += btn_Click;
MovePanel(btn1);
}
private void MovePanel(Control c)
{
var t = new Transition(new TransitionType_Linear(500));
t.add(Panel, "Height", c.Height);
t.add(Panel, "Top", c.Top);
t.run();
}
private void btn_Click(object sender, EventArgs e)
{
MovePanel(sender as Control);
}
}
i want to have a custom close window.
My scenario is:
The original X button function's is to minimize the window, while the custom will actually close it. My default X is like below:
// add handler by double clicking on Closing event in Properties Box
// My below X button
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
this.Hide();
}
However, when i try to create the custom close button like this:
void closeButton_Click(object sender, RoutedEventArgs e)
{
Close();
}
It will just minimize like the default. So how do i it? Thanks for reading.
private bool _forceClose;
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if(!_forceClose)
{
e.Cancel = true;
this.Hide();
}
}
void closeButton_Click(object sender, RoutedEventArgs e)
{
_forceClose = true;
Close();
}
You can remove closing event in the button click
public MainWindow()
{
InitializeComponent();
this.Closing += MainWindow_Closing;
}
void MainWindow_Closing(object sender, CancelEventArgs e)
{
e.Cancel = true;
this.Hide();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Closing -= MainWindow_Closing;
this.Close();
}
I have RadioButton which has a background. Now I need to change background on MouseEnter event. I can do that with
private void button_MouseEnter(object sender, EventArgs e)
{
button.BackgroundImage = Image.FromFile("D:/img/sample.png");
}
But I already have that image as resource in project and I don't know how to get to it.
try as follow:-
private void button_MouseEnter(object sender, EventArgs e)
{
button.BackgroundImage = <YourNameSpace>.Properties.Resources.<ResourceName>;
}
In case you use winforms, include the images to your resource:
public Form1()
{
InitializeComponent();
button1.MouseEnter += new EventHandler(button1_MouseEnter);
button1.MouseLeave += new EventHandler(button1_MouseLeave);
}
void button1_MouseLeave(object sender, EventArgs e)
{
this.button1.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.img1));
}
void button1_MouseEnter(object sender, EventArgs e)
{
this.button1.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.img2));
}