Reputation: 417
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
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).
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
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