您好 我有我的自定义控件,我通过重写OnPaint方法绘制颜色边框。但是,如果鼠标进入控制区域并且鼠标离开控件,我想更改控件的边框颜色。起初我想对事件mouseLeave和mouseEnter做出反应并用适当的颜色重新绘制控件边框。然而,在我的控制下是几个文本框,标签等 - 所以事件mouseEnter和mouseLeave激发了很多次,这导致我的控件闪烁(因为许多重绘)。
有没有更好的方法找到适当的时刻来重绘控件然后对mouseLeave和mouseEnter做出反应?
答案 0 :(得分:2)
只有当鼠标悬停在控件上时,才会使控件无效。您可以通过检查可用于所有控件的静态MousePosition
变量来检查鼠标的位置。只需添加一项检查即可有条件地使您的控件无效。
执行此操作的最简单方法是在MouseEnter
和MouseLeave
事件中执行这些检查,然后进行相应的无效处理。
protected override void OnMouseEnter(EventArgs e)
{
var mousePos = this.PointToClient(MousePosition);
if (this.ClientRectangle.Contains(mousePos))
{
this.Invalidate(invalidateChildren: true);
}
base.OnMouseEnter(e);
}
protected override void OnMouseLeave(EventArgs e)
{
var mousePos = this.PointToClient(MousePosition);
if (!this.ClientRectangle.Contains(mousePos))
{
this.Invalidate(invalidateChildren: true);
}
base.OnMouseLeave(e);
}
要获得更强大的处理方法,您需要确定鼠标是否实际进入或离开您的控件。您需要保留两个变量以保持状态,一个用于判断鼠标当前是否在您的控件上,另一个用于判断鼠标是否在您的控件上(自上次检查后)。如果这些不同,则使控件无效。你会得到额外的好处,知道鼠标是否超过你的控制,所以你可以有条件地在你的绘画方法中执行一些操作。
private bool wasMouseOver;
private bool isMouseOver;
public bool IsMouseOver { get { return isMouseOver; } }
private void CheckMousePosition()
{
var mousePos = this.PointToClient(MousePosition);
wasMouseOver = isMouseOver;
isMouseOver = this.ClientRectangle.Contains(mousePos);
if (isMouseOver != wasMouseOver)
this.Invalidate(invalidateChildren: true);
}
// then register this method to the mouse events
EventHandler mouseHandler = (sender, e) => CheckMousePosition();
MouseEnter += mouseHandler;
MouseLeave += mouseHandler;
MouseMove += (sender, e) => CheckMousePosition();