【发布时间】:2020-03-31 17:22:43
【问题描述】:
我在 c#/WinForms 中创建了一个自定义按钮,除其他外,通过在覆盖的 OnPaint 事件中使用以下代码更改覆盖的 MouseDown 和 MouseUp 事件中按钮的边框粗细,为按钮提供 3-D 感觉:
public int BorderThickness { get; set; } = 3;
public int ClickBorderThickness { get; set; } = 2;
private MouseIsDown = false;
protected override void OnPaint(PaintEventArgs pevent)
{
int BorderWidth = (MouseIsDown) ? ClickBorderThickness : BorderThickness;
ControlPaint.DrawBorder(pevent.Graphics, ClientRectangle,
SystemColors.ControlLightLight, BorderWidth, ButtonBorderStyle.Outset,
SystemColors.ControlLightLight, BorderWidth, ButtonBorderStyle.Outset,
SystemColors.ControlLightLight, BorderWidth, ButtonBorderStyle.Outset,
SystemColors.ControlLightLight, BorderWidth, ButtonBorderStyle.Outset);
//...Other Code...
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
MouseIsDown = true;
Invalidate();
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
MouseIsDown = false;
Invalidate();
}
我还创建了一个重写的 OnClick 事件:
protected override void OnMouseClick(MouseEventArgs e)
{
MouseIsDown = false;
Invalidate();
base.OnMouseClick(e);
}
我认为会发生的情况是,在为我的表单上的按钮执行 Click 事件中的代码之前,该按钮将被重绘并返回其“未单击”外观。这不是发生的事情,并且在表单 Click 事件中的所有代码完成后执行了被覆盖的事件。
如何修改我的自定义按钮以在表单 Click 事件之前执行覆盖的 Click 事件?
【问题讨论】:
-
事件顺序为(调用base前后):MouseDown->Before-MouseDown->After,MouseUp->Before,MouseClick->Before,MouseClick->After,MouseUp->After .所以 MouseClick 方法在调用 base 后 MouseUp 返回之前被调用并完成。但是调用base之前
MouseUp中的代码当然是在MouseClick之前执行的。Invalidate()将消息排入队列,该消息将在被覆盖的方法返回后处理。请注意,当您单击按钮时,无论如何都会调用 OnPaint,因此此处的所有 Invalidate 调用仅在 MouseUp->After 之后添加一个额外的 OnPaint 调用。
标签: c# winforms custom-controls