K. Ajay
K. Ajay

Reputation: 417

How to call Paint event on MouseHover?

I have a panel's Paint event which draws a rectangle around the panel to highlight it.

Paint event-

 private void deal_details_panel_Paint(object sender, PaintEventArgs e)
        {
          int thickness = 2;//it's up to you
            int halfThickness = thickness / 2;
            using (Pen p = new Pen(Color.GreenYellow, thickness))
            {
                e.Graphics.DrawRectangle(p, new Rectangle(halfThickness,
                                                          halfThickness,
                                                          deal_details_panel.ClientSize.Width - thickness,
                                                          deal_details_panel.ClientSize.Height - thickness));
            }

        }

Initially i dont want this rectangle to be shown, I have a button on which if i hover, only then i want to show this rectangle and on MouseLeave event i want to make it invisible again.

Button_Hover-

private void add_MouseHover(object sender, EventArgs e)
        {



            deal_details_panel.Invalidate();



        }

I saw some answers which were to use Invalidate(), but, Invalidate() is not working for me.

Upvotes: 1

Views: 1405

Answers (2)

Zohar Peled
Zohar Peled

Reputation: 82474

Use Refresh() instead of Invalidate().

The Invalidate() method does not force repaint, it simply marks the control as "need repainting", leaving it up to the OS to repaint when needed.

The Refresh() method will force repainting immediately.

For more information, read Whats the difference between Control.Invalidate, Control.Update and Control.Refresh? blog post, where it clearly states:

Control.Invalidate( ) / Control.Invalidate(bool) / Control.Invalidate(Rectangle) / Control.Invalidate(Rectangle, bool) / Control.Invalidate(Region) / Control.Invalidate(Region, bool) .... The important thing to note here is that these functions only “invalidate” or “dirty” the client area by adding it to the current update region of the window of the control. This invalidated region, along with all other areas in the update region, is marked for painting when the next WM_PAINT message is received. As a result you may not see your control refreshing (and showing the invalidation) immediately (or synchronously).

Update

In order for the panel to show the YellowGreen border only when the mouse is hovering over the button, you need to change your code a little bit.

First, add a bool field to your form, to indicate whether to draw the border or not, initialized to false:

private bool _drawBorder = false;

Then, change the paint method to take that value into consideration:

private void deal_details_panel_Paint(object sender, PaintEventArgs e)
{
    if(_drawBorder)
    {
        int thickness = 2;//it's up to you
        int halfThickness = thickness / 2;
        using (Pen p = new Pen(Color.GreenYellow, thickness))
        {
            e.Graphics.DrawRectangle(p, new Rectangle(halfThickness,
                                                      halfThickness,
                                                      deal_details_panel.ClientSize.Width - thickness,
                                                      deal_details_panel.ClientSize.Height - thickness));
        }
    }
}

Finally, don't use the mouse_Hover event on the button, use MouseEnter and MouseLeave instead.
This is for two reasons - 1: Mouse_Hover have a built in delay and 2: using Mouse_Hover you don't get an indication when the mouse stops hovering over the button.

In the MouseEnter and MouseLeave event handlers, all you need to do is update the value of _drawBorder and call deal_details_panel.Refresh():

private void add_MouseEnter(object sender, EventArgs e)
{
    _drawBorder = true;
    deal_details_panel.Refresh();
}

private void add_MouseLeave(object sender, EventArgs e)
{
    _drawBorder = false;
    deal_details_panel.Refresh();
}

Upvotes: 1

Matěj Štágl
Matěj Štágl

Reputation: 1037

Zohar pointed correct solution but I would add a suggestion to change:

using (Pen p = new Pen(Color.GreenYellow, thickness))

to:

using (Pen p = new Pen(Color.Transparent, thickness))

This will set correct state from the start so no need to repaint.

Upvotes: 0

Related Questions