C#检查是否控制';孩子的父母失去了注意力

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

我有一个自定义控件,一个悬停按钮,只要鼠标移动到它上面或获得焦点,它就会显示边框

一切正常,但我在处理以下情况时遇到问题:单击按钮,它会显示另一个窗体(ShowDialog)或(MessageBox),然后返回控件的父窗体

这是控制代码:

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)

这里有什么问题?关闭模式对话框时,您希望应用哪种效果?0、3或其他?问题是,当我将按钮设置为显示消息时,在消息关闭之前,无法访问按钮的父级(窗体)。因此,我可以使用这两个表单对按钮进行任何更改。这两个表单之间没有任何连接。非常感谢。我一到家就试试