如何在MouseHover上调用Paint事件?

时间:2018-08-08 10:35:02

标签: c# visual-studio winforms

我有一个面板的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()对我不起作用。

2 个答案:

答案 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事件,而应使用MouseEnterMouseLeave
这有两个原因-1:Mouse_Hover具有内置的延迟; 2:使用Mouse_Hover,当鼠标停止悬停在按钮上方时,您没有任何指示。

MouseEnterMouseLeave事件处理程序中,您需要做的就是更新_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))

这将从一开始就设置正确的状态,因此无需重新绘制。