MouseHover and MouseLeave Events controlling

2019-01-20 13:21发布

问题:

I was building a simple form with one simple effect- opacity reduced when mouse is not over the form, and form becomes opaque when mouse is over it. I am currently encountering couple of difficulties:-

  1. Firstly, I did this-

     this.MouseHover += new EventHandler(Form1_MouseHover);
     this.MouseLeave += new EventHandler(Form1_MouseLeave);
    

    But I had 1 richtextbox in form too, and as mouse went over it, the form lost opacity again. I had to add this too:-

     richTextBox1.MouseHover+=new EventHandler(Form1_MouseHover);
     richTextBox1.MouseLeave+=new EventHandler(Form1_MouseLeave);
    

    wondering if there was any better way,because there is still some gap between richtextbox and form boundaries, and form is losing opacity when mouse cursor goes there.

  2. If the mouse is NOT over the form (suppose initially), the form is less opaque. Now, I want form to become opaque as soon as mouse goes over it, but it only happens when mouse movement over form stops completely. If I keep moving mouse over the form, it does not become opaque. Is this a problem with the way events are stored in message queue and all that or will I be able to do something, because I have seen applications with the effect I am trying to implement.

回答1:

The MouseEnter/Leave events are too unreliable to do this. Best thing to do is just use a Timer that checks if the mouse is still inside the window. Drop a Timer on the form and make the code look like this:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
        this.Opacity = 0.99;
        timer1.Interval = 200;
        timer1.Enabled = true;
        timer1.Tick += timer1_Tick;
    }
    protected override void OnLoad(EventArgs e) {
        base.OnLoad(e);
        timer1_Tick(this, e);
    }
    private void timer1_Tick(object sender, EventArgs e) {
        this.Opacity = this.Bounds.Contains(this.PointToClient(Cursor.Position)) ? 0.99 : 0.20;
    }
}

Btw: avoid increasing the Opacity to 1.0, that forces the native window to be recreated and that can have a lot of side-effects. Using 0.99 is best.



回答2:

I might be wrong, but why would you use MouseHover event? MouseHover detects when the mouse stop moving on the form and is usually used to show Tooltips.

The event you are looking for is MouseEnter which is the opposite of MouseLeave and detects when the mouse enters the client rect of a window.

In the Leave event, just check if the cursor position is in the window client rect to know if it did actually leave the form or if it is just on top of child control.

Ofc if you use a region, you'll have to adapt the code.

 private void Form1_MouseEnter(object sender, EventArgs e)
    {
        this.Opacity = 1;
    }

    private void Form1_MouseLeave(object sender, EventArgs e)
    {

        if (!this.ClientRectangle.Contains(this.PointToClient(Cursor.Position)))
        {
            this.Opacity = 0.5;
        }
    }


回答3:

Add a timer control then use below in timer's tick event. Above answers won't work if you have custom/user controls in your form. So have to use ClientRectangle

this.Opacity = this.ClientRectangle.Contains(this.PointToClient(Cursor.Position)) ? 0.99 : 0.20;


回答4:

private void Form1_MouseEnter(object sender, EventArgs e)
{
    this.Opacity = 1.0;
}

private void Form1_MouseLeave(object sender, EventArgs e)
{ 
    this.Opacity = 0.8;
}


标签: c# opacity