Click here to Skip to main content
15,890,897 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello all, i would like to know how to tell whither or not the mouse is hovering over a winform app.
i think i have to hook in to either the Gotfocus, LostFocus, MouseHover or the MouseEnter Events
here is what i got so far:

C#
this.MouseEnter += new System.EventHandler(this.Form1_MouseHover);

public void Form1_MouseHover(object sender, System.EventArgs e) 
{
    this.Opacity = 0.5;
}

what i want to do is determine whither or not the mouse is hovering over the form and if it is then set the form Opacity to 1.0 but if it isn't then set the Opacity to 0.5
how would i do this?
also how would i am smoothly animate the transitions between the Opacity values of 1.0 and 0.5?
thanks for all of your help in advance,
MasterCodeon
Posted
Updated 11-Dec-14 9:59am
v3
Comments
BillWoodruff 11-Dec-14 23:24pm    
I suggest that (as Macin's solution shows you how to) you use the 'MouseEnter event rather than 'MouseHover: the MouseHover trigger delay-interval is a system-wide setting that may reflect the user's preference (if they've changed it).

You might also consider when the Form is fully opaque after you re-enter it, bringing the Form to the front ?

1 solution

Hi!

This is very simple. To animate transitions you can use Timer component. Sample code:

C#
public partial class Form1 : Form
{
    private const double OPACITY_MIN = 0.5;
    private const double OPACITY_MAX = 1.0;
    private const double OPACITY_STEP = 0.05;   // Step for changing opacity value
    private const int TIMER_INTERVAL = 100;     // Interval in miliseconds (1/1000 of second)

    private Timer _timer;                       // Timer control
    private bool _fading = false;               // Opacity mode: fading or showing

    public Form1()
    {
        InitializeComponent();
        
        // Configure time, but don't start yet
        _timer = new Timer();
        _timer.Interval = TIMER_INTERVAL;       // Set interval
        _timer.Tick += _timer_Tick;             // Set timer Tick event handler
    }

    // This method is executed every TIMER_INTERVAL miliseconds is Timer is enabled
    private void _timer_Tick(object sender, EventArgs e)
    {
        // Decrease or increase value of Form's opacity property by OPACITY_STEP in every timer Tick
        // and stop the timer if MIN or MAX opacity value was reached
        if (_fading)
        {
            if (this.Opacity > OPACITY_MIN)
            {
                this.Opacity -= OPACITY_STEP;
            }
            else
            {
                this.Opacity = OPACITY_MIN;
                _timer.Enabled = false;
            }
        }
        else
        {
            if (this.Opacity < OPACITY_MAX)
            {
                this.Opacity += OPACITY_STEP;
            }
            else
            {
                this.Opacity = OPACITY_MAX;
                _timer.Enabled = false;
            }
        }
    }

    private void Form1_MouseLeave(object sender, EventArgs e)
    {
        // When mouse is leaving form we are setting mode to Fading and enabling timer
        _fading = true;
        _timer.Enabled = true;
    }

    private void Form1_MouseEnter(object sender, EventArgs e)
    {
        // When mouse is entering form we are setting mode to Showing and enabling timer
        _fading = false;
        _timer.Enabled = true;
    }
}


You can handle other Form's events in the same way. But you should remember that if you place i.e. Panel control and set Dock property to Dock.Fill this code will not work. You will have to handle Panel's events (Enter and Leave).

http://msdn.microsoft.com/en-us/library/system.windows.forms.timer%28v=vs.110%29.aspx[^]

[Update for Bill Woodruff's comment]
MouseHover event isn't fired immediatelly when mouse enters the form. According to MSDN documentation:
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.mousehover%28v=vs.110%29.aspx[^]

there is some amount of time before that event is fired:
http://msdn.microsoft.com/en-us/library/system.windows.forms.systeminformation.mousehovertime%28v=vs.110%29.aspx[^]
and specified area within which the mouse pointer has to stay before event is fired:
http://msdn.microsoft.com/en-us/library/system.windows.forms.systeminformation.mousehoversize%28v=vs.110%29.aspx[^]

So, using MouseEnter and MouseLeave is first choice. The second choice should be Form's Activated and Deactivated events which are fired when you i.e. switch to/from another window/app.
-- End update --

[Update - For MasterCodeon's comment]
I admit that didn't test this solution with controls placed on form. In that situation Form's MouseEnter and MouseLeave will be fired even when mouse cursor will enter/leave controls located on form.
So, I have found workaround to this problem entirely based on Timer. Basically I got rid of MouseEnter and MouseLeave event handlers and added checking (for some interval) that cursor's position is within Form's bounds.
Additionally I've added an option (SMOOTH_SHOWING) for setting behaviour how form will appear when cursor enters the form. If set to yes, then form will be shown smoothly (like in fading), if no then form will appear immediatelly. Below is my code:
C#
public partial class Form1 : Form
{
    private const double OPACITY_MIN = 0.5;
    private const double OPACITY_MAX = 1.00;
    private const double OPACITY_STEP = 0.05;
    private const bool SMOOTH_SHOWING = true;   // If True then form will appear smoothly otherwise it will be shown immediatelly
    private const int TIMER_INTERVAL = 100;

    private Timer _timer;

    public Form1()
    {
        InitializeComponent();

        _timer = new Timer();
        _timer.Interval = TIMER_INTERVAL;
        _timer.Tick += _timer_Tick;
        _timer.Enabled = true;
    }

    void _timer_Tick(object sender, EventArgs e)
    {
        var inside = this.Bounds.Contains(Cursor.Position);
        if (inside) // Showing
        {
            if (this.Opacity < OPACITY_MAX)
            {
                if (SMOOTH_SHOWING)
                {
                    this.Opacity += OPACITY_STEP;
                }
                else
                {
                    this.Opacity = OPACITY_MAX;
                }
            }

        }
        else        // Fading
        {
            if (this.Opacity > OPACITY_MIN)
            {
                this.Opacity -= OPACITY_STEP;
            }
        }
    }
}

-- End update ---

I hope it help you.
 
Share this answer
 
v4
Comments
BillWoodruff 11-Dec-14 23:22pm    
+5 I like the fact you used the 'MouseEnter Event rather than 'MouseHover, and I've made a comment to the OP about the possible draw-back of 'MouseHover.
Marcin Kozub 12-Dec-14 2:22am    
Thx Bill! Your comments are always very welcome :)
MasterCodeon 16-Dec-14 13:19pm    
ah thank you so much!
i opened a new winform project and i had to change the timer name and i had to subscribe to the MouseEnter and MouseLeave events, and i had to start the timer on the Form_Load Method but with those few little modifications it works!
thank you so much!
Marcin Kozub 16-Dec-14 13:29pm    
I don't understand why are you starting Timer at Form_Load method? Timer should be enabled only on Mouse Enter/Leave event handlers and disabled only when opacity reach specific value (which in fact is increased/decreased) in Timer's Tick event. Maybe I miss some point? This example works fine without any modifications :)
MasterCodeon 16-Dec-14 14:10pm    
Yeah the timer does start when either event is fired I just didn't realize it did (he he oops)
Moreover, as far as modifications go I only switched out the names and used the designer to do the event handling of the timer.
I also have another question about this, why doesn't this work for all the buttons and other controls as well?
because when ever I put my mouse over the background of the form it will fade to and fro like it’s supposed to but whenever I put my mouse over a control(like a button or a textbox) it won't fade to or back.
I reasoned that I should subscribe to the MouseEnter and the MouseLeave events for each control in the form using a foreach loop:

<pre lang="c#">

foreach (Control ctrl in this.Controls)
{
ctrl.MouseEnter += new System.EventHandler(this.Form1_MouseEnter);
ctrl.MouseLeave += new System.EventHandler(this.Form1_MouseLeave);
}
</pre>
(Sorry if the code doesn't display properly in the comment, I don't know comments can use the C# code tags)
Now this doesn't work quite right because when I use this loop it still doesn’t fade in and out for all the controls in the form.
How do I fix that?
Thanks for all your help again

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900