【问题标题】:Why does custom WinForms control not adhere to properties set in constructor when drawn?为什么自定义 WinForms 控件在绘制时不遵守构造函数中设置的属性?
【发布时间】:2026-01-06 16:55:01
【问题描述】:

我有一个继承自 System.Windows.Forms.TextBox 的自定义文本框控件。

基本上我将其设置为在每次文本更改时自动检查输入的值是否为数字。示例代码:

public class MyTextBox : TextBox {

    public MyTextBox() : base() {
        base.TextChanged += MyTextBox_TextChanged;
        base.BackColor = Color.White;
        base.ForeColor = Color.Black;
    }

    private void MyTextBox_TextChanged(object sender, EventArgs e) {
        try {
            int.Parse(base.Text);
            base.BackColor = Color.White;
            base.ForeColor = Color.Black;
        } catch(FormatException) {
            base.BackColor = Color.Red;
            base.ForeColor = Color.White;
        }
    }
}

如上所述,我的默认背景和前景分别为WhiteBlack,但是 WinForms 设计器将组件绘制为具有红色背景,并且在我启动程序时也会出现这种情况.但是,当我开始输入数字时,它确实会变回黑/白,否则会按预期运行。

但是为什么控件似乎覆盖了我在构造函数中设置的属性呢?最初绘制控件时,文本没有改变......或者是这样吗?

【问题讨论】:

  • 您是在将控件放到表单上之后还是之前添加了此代码?
  • 可能已经过了,但是当我进行更改时,我总是重新构建解决方案,但似乎仍然无法纠正它
  • 当您将控件放到表单上时,表单设计器会将当前颜色保存到表单设计器代码中。您在控件的构造函数中对相同属性所做的更改会立即被拥有该控件的窗体覆盖。您应该再次删除并删除控件,看看是否有帮助。重建对解决这个问题没有帮助。您还可以转到表单的 .Designer.cs 文件并删除有问题的行,但在更改其代码后再次删除和删除控件会更安全。
  • 仍然不起作用,我确实看到 Designer.cs 正在覆盖颜色设置,但为什么呢?更改颜色的代码只应该在文本更改时运行。将控件放在表单上时文本是否“更改”?
  • 是的,控件的当前文本也被保存并设置回表单设计器代码中的控件。由于文本框的初始文本是空字符串,无法解析,因此您会得到红色。

标签: c# winforms


【解决方案1】:

当您将控件拖放到表单上时,其当前属性由表单设计器保存。

这包括以下内容:

  • 前景色
  • 背景色
  • 文字

当您构造表单时,这些属性会被设置回控件。​​

在控件的构造函数中,您将背景颜色设置为白色,但您不更改文本,因此 text 属性保持为空字符串。

这个空字符串无法解析,所以现在我们有两种可能的情况:

  • BackColor 由表单设计器代码在 Text 之前设置,在这种情况下,TextChanged 的​​事件处理程序获胜。由于文本是空字符串,无法解析,所以背景色虽然暂时是白色,但立即变为红色
  • 正好相反,设置了文本,解析失败,背景颜色设置为红色,然后表单设计器将保存的背景颜色设置回白色。

控件属性是按字母顺序设置的(​​如果我没记错的话),所以第一个场景就是你看到的那个。

简而言之,您有几种方法可以处理此问题:

  • 确定空字符串是否合法,尽管可能带有一些默认值(可能是 null?)
  • 确保控件的构造函数为其分配了一个合法可解析整数值的文本(想到0

【讨论】:

    最近更新 更多