我有一个面板的Paint事件,该事件在面板周围绘制一个矩形以突出显示它。
绘画活动-
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));
}
}
最初我不希望显示该矩形,我有一个按钮,如果我将鼠标悬停在该按钮上,则只有我想要显示此矩形,并且在MouseLeave事件上,我想使其再次不可见。
Button_Hover-
private void add_MouseHover(object sender, EventArgs e)
{
deal_details_panel.Invalidate();
}
我看到了一些使用Invalidate()的答案,但是Invalidate()对我不起作用。
答案 0 :(得分:1)
使用Refresh()
代替Invalidate()
。
Invalidate()
方法不会强制重绘,它只是将控件标记为“需要重绘”,而留给OS以便在需要时重绘。
Refresh()
方法将立即强制重新粉刷。
有关更多信息,请阅读Whats the difference between Control.Invalidate, Control.Update and Control.Refresh?博客文章,其中明确指出:
Control.Invalidate()/Control.Invalidate(布尔)/Control.Invalidate(矩形)/Control.Invalidate(矩形,布尔)/Control.Invalidate(区域)/Control.Invalidate(区域,布尔) .... 这里要注意的重要一点是,这些功能仅通过将客户区添加到控件窗口的当前更新区域中来“无效”或“弄脏”客户区。当接收到下一个WM_PAINT消息时,此无效区域以及更新区域中的所有其他区域将标记为绘制。结果,您可能看不到控件立即(或同步)刷新(并显示无效)。
为使面板仅在鼠标悬停在按钮上时才显示YellowGreen边框,您需要稍作更改。
首先,在表单中添加一个布尔字段,以指示是否绘制边框,并将其初始化为false:
private bool _drawBorder = false;
然后,更改paint
方法以将该值考虑在内:
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));
}
}
}
最后,不要在按钮上使用mouse_Hover事件,而应使用MouseEnter
和MouseLeave
。
这有两个原因-1:Mouse_Hover具有内置的延迟; 2:使用Mouse_Hover,当鼠标停止悬停在按钮上方时,您没有任何指示。
在MouseEnter
和MouseLeave
事件处理程序中,您需要做的就是更新_drawBorder
的值并调用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();
}
答案 1 :(得分:0)
Zohar指出了正确的解决方案,但我会提出更改建议:
using (Pen p = new Pen(Color.GreenYellow, thickness))
收件人:
using (Pen p = new Pen(Color.Transparent, thickness))
这将从一开始就设置正确的状态,因此无需重新绘制。