C#检查是否控制';孩子的父母失去了注意力
我有一个自定义控件,一个悬停按钮,只要鼠标移动到它上面或获得焦点,它就会显示边框 一切正常,但我在处理以下情况时遇到问题:单击按钮,它会显示另一个窗体(ShowDialog)或(MessageBox),然后返回控件的父窗体 这是控制代码:C#检查是否控制';孩子的父母失去了注意力,c#,event-handling,custom-controls,C#,Event Handling,Custom Controls,我有一个自定义控件,一个悬停按钮,只要鼠标移动到它上面或获得焦点,它就会显示边框 一切正常,但我在处理以下情况时遇到问题:单击按钮,它会显示另一个窗体(ShowDialog)或(MessageBox),然后返回控件的父窗体 这是控制代码: namespace CustomControlTutorial { using System; using System.Drawing; using System.Drawing.Drawing2D; using System
namespace CustomControlTutorial
{
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
public partial class HoverButton : Button
{
byte eventPaintMode = 0;
//Color borderClr = Color.Transparent;
public HoverButton()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs pe)
{
//base.OnPaint(pe);
// render background
Color clr = this.Parent.BackColor;
Brush b = new SolidBrush(clr);
pe.Graphics.FillRectangle(b, ClientRectangle);
// Draw borders depending on event case
Point p00 = new Point(0, 0);
Point p01 = new Point(0, ClientSize.Height - 1);
Point p10 = new Point(ClientSize.Width - 1, 0);
Point p11 = new Point(ClientSize.Width - 1, ClientSize.Height - 1);
Pen pen1;
Pen pen2;
switch (eventPaintMode)
{
case 1:
{
// draw borders (using pen)
pen1 = new Pen(new SolidBrush(Color.DimGray), 1);
pen2 = new Pen(new SolidBrush(Color.White), 1);
pe.Graphics.DrawLine(pen1, p10, p11);
pe.Graphics.DrawLine(pen2, p00, p10);
pe.Graphics.DrawLine(pen1, p01, p11);
pe.Graphics.DrawLine(pen2, p00, p01);
break;
}
case 2:
{
pen2 = new Pen(new SolidBrush(Color.DimGray), 1);
pen1 = new Pen(new SolidBrush(Color.White), 1);
pe.Graphics.DrawLine(pen1, p10, p11);
pe.Graphics.DrawLine(pen2, p00, p10);
pe.Graphics.DrawLine(pen1, p01, p11);
pe.Graphics.DrawLine(pen2, p00, p01);
break;
}
case 3:
{
// draw borders (using pen)
pen1 = new Pen(new SolidBrush(Color.DimGray), 1);
pen2 = new Pen(new SolidBrush(Color.White), 1);
pe.Graphics.DrawLine(pen1, p10, p11);
pe.Graphics.DrawLine(pen2, p00, p10);
pe.Graphics.DrawLine(pen1, p01, p11);
pe.Graphics.DrawLine(pen2, p00, p01);
// draw focus lines
pen1 = new Pen(new SolidBrush(Color.Black), 1);
pen1.DashCap = DashCap.Round;
pen1.DashPattern = new float[] { 1, 1, 1, 1 };
p00 = new Point(5, 5);
p01 = new Point(5, ClientSize.Height - 6);
p10 = new Point(ClientSize.Width - 6, 5);
p11 = new Point(ClientSize.Width - 6, ClientSize.Height - 6);
pe.Graphics.DrawLine(pen1, p10, p11);
pe.Graphics.DrawLine(pen1, p00, p10);
pe.Graphics.DrawLine(pen1, p01, p11);
pe.Graphics.DrawLine(pen1, p00, p01);
pe.Graphics.SmoothingMode = SmoothingMode.None;
break;
}
default:
break;
}
// render text
String drawString = this.Text;
SizeF size = pe.Graphics.MeasureString(drawString, this.Font);
float pointX = ((float)ClientSize.Width - size.Width) / 2;
float pointY = ((float)ClientSize.Height - size.Height) / 2;
pe.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), (int)pointX, (int)pointY);
b.Dispose();
}
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
eventPaintMode = 1;
Invalidate();
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
eventPaintMode = 0;
Invalidate();
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (e.Button == MouseButtons.Left)
{
eventPaintMode = 2;
Invalidate();
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (e.Button == MouseButtons.Left)
{
eventPaintMode = 1;
Invalidate();
}
}
protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
eventPaintMode = 3;
Invalidate();
}
protected override void OnLostFocus(EventArgs e)
{
base.OnLostFocus(e);
eventPaintMode = 0;
Invalidate();
}
}
}
这是我显示测试消息框的地方:
private void hoverButton1_Click(object sender, EventArgs e)
{
MessageBox.Show("Test");
}
我找不到像OnParentLostFocus之类的事件
问题是,当我将按钮设置为显示消息时,在消息关闭之前,无法访问按钮的父级(窗体)。因此,我可以使用这两个表单对按钮进行任何更改 这就是它的工作原理。只要显示模式对话框,来自的父对象及其子对象将不会收到windows paint消息以重新绘制自己 您的代码创建: 如您所见,该按钮在制表位上绘制了两种不同的效果。悬停和聚焦效果。它绘制悬停效果并忽略鼠标指针上的焦点,即使控件当前具有焦点。另一件事是,当模式对话框关闭时,按钮不会显示或绘制正常/默认状态 嗯,这两件事不应该结合在一起,与鼠标事件交互以绘制悬停和向下效果,并在控件获得焦点且未应用鼠标效果时绘制焦点矩形。就像默认的
System.Windows.Forms.Button
一样
例如:
//您的命名空间。。。
公共枚举:int
{
没有,结束,结束
}
[设计分类(“代码”)]
公共类悬停按钮:按钮
{
private MouseState state=MouseState.None;
公共悬停按钮():base()
{
固定方式(
ControlStyles.AllPaintingWimPaint|
ControlStyles.UserPaint|
ControlStyles.ResizerDraw,true);
UpdateStyles();
}
受保护的覆盖无效OnPaint(PaintEventArgs e)
{
var g=e.图形;
var r=ClientRectangle;
g、 清晰(父级背景色);
var p00=新点(0,0);
var p01=新点(0,r.高度-1);
变量p10=新点(r.宽度-1,0);
变量p11=新点(r.宽度-1,r.高度-1);
开关(状态)
{
案件编号:MouseState
if(r.Contains(PointToClient(MousePosition)))
{
g、 抽绳(Pens.DimGray,p10,p11);
g、 抽绳(白色,p00,p10);
g、 抽绳(Pens.DimGray,p01,p11);
g、 抽绳(白色,p00,p01);
}
打破
case MouseState.Down:
g、 抽绳(白色、p10、p11);
g、 抽绳(Pens.DimGray,p00,p10);
g、 抽绳(白色,p01,p11);
g、 抽绳(Pens.DimGray,p00,p01);
打破
违约:
打破
}
TextRenderer.DrawText(g、文本、字体、r、前景色、,
TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
if(聚焦&&MouseButtons==MouseButtons.None&&
!r.Contains(指向客户端(鼠标位置)))
{
r、 充气(-2,-2);
ControlPaint.DrawFocusRectangle(g,r);
}
}
MouseCenter上受保护的覆盖无效(事件参数e)
{
base.onmouseinter(e);
state=MouseState.Over;
使无效();
}
MouseLeave上的受保护覆盖无效(事件参数e)
{
基地,离港(e);;
state=MouseState.None;
使无效();
}
MouseEventArgs e上的受保护覆盖无效(MouseEventArgs e)
{
base.OnMouseDown(e);
if(e.Button==MouseButtons.Left)
{
state=MouseState.Down;
使无效();
}
}
MouseUp上的受保护覆盖无效(MouseEventArgs e)
{
base.OnMouseUp(e);
state=MouseState.Over;
使无效();
}
受保护的覆盖void OnEnter(事件参数e)
{
基元数(e);
state=MouseState.None;
使无效();
}
受保护的覆盖void OnLeave(事件参数e)
{
底面无檐(e);
state=MouseState.None;
使无效();
}
}
这就产生了:
旁注
- 调用
方法以清除具有所需颜色的绘图画布e.Graphics.Clear(..)
- 尽可能使用预定义的图形对象,而不是创建新的图形对象
- 在控件上绘制字符串更好,而
在图像上绘制字符串更好e.Graphics.DrawString(..)
- 要使控件中的文本居中,请将其绘制在矩形中,并使用重载,在重载中可以传递(或使用
方法)来指示该文本以及其他文本布局信息Graphics.DrawString(..)
- 不要忘记处理图形对象(代码中的pen1和pen2)