在Button_Click上的Control周围绘制边框

时间:2010-02-03 16:35:29

标签: c# .net winforms .net-3.5 controls

当用户点击我的验证按钮(我的C#,WinForm,.net 3.5应用程序中的)时,如果它是空的,我想在某个控件周围画一个边框。说一个名为tbxLastName的文本框我以为我需要做这样的事情 - >

ControlPaint.DrawBorder(Graphics.FromHwnd(this.Handle), 
    tbxLastName.ClientRectangle, Color.Firebrick, ButtonBorderStyle.Solid);

不幸的是,我不知道要为图形对象添加什么,就像我没有做的那样。

我遇到的所有示例MSDN - HERE都在Paint事件中包含此代码。像这样 - >

private void panel1_Paint(object sender, PaintEventArgs e)
{    
    ControlPaint.DrawBorder(e.Graphics, this.panel1.ClientRectangle, 
        Color.DarkBlue, ButtonBorderStyle.Solid);
}

但是,我只希望在符合条件的情况下显示边框,这是由Button_Click启动的


许多建议建议使用容器对象来保存文本框并将其称为Paint_Event。我做了这个,出现了一个方框但不在控件周围。它出现在Container Control的左上角。这是我正在做的事情 - >

    private void grpImmunizationCntrl_Paint(object sender, PaintEventArgs e)
    {
        if (lkuNOImmunizationReason.Text.Equals(string.Empty)
        {
           ControlPaint.DrawBorder(
                    e.Graphics, lkuNOImmunizationReason.ClientRectangle,
                        Color.Firebrick, ButtonBorderStyle.Solid);
        }
    }

修改

这就是我提出的将这些建议与对我有用的建议相结合。

    public static void HighlightRequiredFields(Control container, Graphics graphics, Boolean isVisible)
    {
        Rectangle rect = default(Rectangle);
        foreach (Control control in container.Controls)
        {
            if (control.Tag is string && control.Tag.ToString() == "required")
            {
                rect = control.Bounds;
                rect.Inflate(3, 3);
                if (isVisible && control.Text.Equals(string.Empty))
                {
                    ControlPaint.DrawBorder(graphics, rect, Color.FromArgb(173,216,230), ButtonBorderStyle.Solid);
                }
                else
                {
                    ControlPaint.DrawBorder(graphics, rect, container.BackColor, ButtonBorderStyle.None);
                }
            }

            if (control.HasChildren)
            {
                foreach (Control ctrl in control.Controls)
                {
                    HighlightRequiredFields(ctrl, graphics, isVisible);
                }
            }
        }
    }

我从我需要的任何容器的Paint_Event中调用它。

5 个答案:

答案 0 :(得分:3)

您可以使用表单中的操作列表字段并添加或删除自定义绘图:

// field
List<Action<Graphics>> drawings = new List<Action<Graphics>>();

// on click event:
drawings.Add(delegate(Graphics g) {
    var rect = tbxLastName.Bounds;
    rect.Inflate(1, 1); // make rectange a bit larger than textbox
    ControlPaint.DrawBorder(g, rect, 
    Color.DarkBlue, ButtonBorderStyle.Solid);
});
// make sure you added only once or clear before
panel1.Refresh(); // refresh panel to force painting


// Paint method:
foreach (var draw in drawings) {
    draw(e.Graphics);
}

这样您可以添加多个边框

答案 1 :(得分:2)

我在VB.Net上做了类似的事情,在这个帖子的帮助下。我的每个控件周围都有一个Panel容器,在OnPaint的{​​{1}}处理程序中,我遍历Panel中的所有子控件并绘制边框如果他们有Panel,他们就在他们身边。我只在Edit或New上显示边框,所以我创建了tag="required"参数来打开和关闭这些边框。如果我要解除此问题,请拨打fVisible,以便触发Panel.Refresh()事件。这样我所要做的就是在设计时在所需的控件上设置标签,并为容器面板添加一个处理程序,它们都是动态的。

这是我从我的所有Panel OnPaint事件处理程序调用的共享函数。 (对不起,我知道你使用的是C#,这是VB,但它非常基本。)

OnPaint

答案 2 :(得分:1)

文本框不会调用OnPaint方法(请参阅this pageNote部分)。绕过这个方法,就是将文本框放在一个略大的面板中。然后,只要单击按钮,就更改背景颜色。 MSDN forums处的线程有一些解决方案。

修改 要澄清面板解决方案,只需创建一个面板并将文本框添加到其中: e.g。

private void MyForm_Load(object sender, EventArgs e)
{
     myPanel.Controls.Add(tbxLastName); //Make sure the panel size is slightly bigger than the text box (so that it looks like a border)
}

然后,处理按钮点击事件:

private void myButton_Click(object sender, EventArgs e)
    {
        if (tbxLastName.Text == "")
        {
            myPanel.BackColor = Color.Red;
        }
        else
        {
            myPanel.BackColor = Color.Transparent;
        }
    }

答案 3 :(得分:1)

    protected override void OnTextChanged(EventArgs e)
    {
        base.OnTextChanged(e);
        if (string.IsNullOrEmpty(Text))
        {
            this.BorderStyle = BorderStyle.FixedSingle;
        }
        else 
        {
            this.BorderStyle = BorderStyle.Fixed3D;
        }
    }

答案 4 :(得分:1)

矩形“缺少”文本框的原因是ClientRectangle仅包含控件的大小,而不是位置。试试这个:

private void grpImmunizationCntrl_Paint(object sender, PaintEventArgs e)
{
    if (lkuNOImmunizationReason.Text.Equals(string.Empty)
    {
       ControlPaint.DrawBorder(
                e.Graphics, new Rectangle(lkuNOImmunizationReason.Left, lkuNOImmunizationReason.Top, lkuNOImmunizationReason.ClientRectangle.Width, lkuNOImmunizationReason.ClientRectangle.Height),
                    Color.Firebrick, ButtonBorderStyle.Solid);
    }
}