【发布时间】:2020-08-29 11:36:47
【问题描述】:
我正在尝试创建一个简单的文本框,该文本框在未获得焦点且文本为空时显示提示文本,并在获得焦点时隐藏提示文本。为此,我通过扩展 TextBox 创建了一个自定义控件。
public partial class HintedTextBox : TextBox
{
private Color foreColor;
public HintedTextBox()
{
InitializeComponent();
foreColor = ForeColor;
GotFocus += OnFocused;
LostFocus += OnFocusLost;
OnFocusLost(null, null); // Problem
}
public string Hint { get; set; }
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
}
private void OnFocused(object sender, EventArgs e)
{
if (Text == Hint)
{
Text = "";
ForeColor = foreColor;
}
}
private void OnFocusLost(object sender, EventArgs e)
{
if (Text.Trim() == "")
{
Text = Hint;
ForeColor = Color.Gray;
}
else
{
ForeColor = foreColor;
}
}
}
从逻辑上讲,我需要在组件初始化后调用OnFocusLost() 过程,以便应用程序在首次显示表单时显示提示。问题出在我用// problem 标记的那一行。在这一行,我的自定义属性Hint 和库存属性Text 都没有初始化,即使我已经在设计器中设置了它们的值。奇怪的是ForeColor 属性已经在该行初始化。是否有其他事件在这些值初始化后立即触发,或者是否有其他解决方案?
我还尝试从 Windows 窗体的 FormLoad 事件的控件外部调用 OnFocusLost()。它也不起作用。 Text 和 Hint 在开始时总是空的,即使在 InitializeComponent() 调用之后也是如此。
感谢您的关注。
编辑:
我忘记将表单的加载事件附加到我的 FormLoad() 方法中,但 Vladimir Stoyanov 的解决方案非常有效,甚至更好。
【问题讨论】:
-
定义“初始化”。这些属性肯定会被初始化,因为这是一个基本的 C# 功能。不过,它们可能只被初始化为其默认值。如果您期望它们被初始化为其他值,通常会在
InitializeComponent()方法用于包含对象 中处理,即Form子类。自然,该代码还不能在这里执行,因为构造函数还没有返回。如果您希望在设置Hint时引发事件,则由您来实现。 ... -
... 您继承的
Text属性已经有一个TextChanged事件。您根本没有发布任何InitializeComponent()方法,更不用说期望这些属性被初始化的任何代码,因此任何人都不可能正确回答您的问题。请参阅minimal reproducible example 和How to Ask。 -
@PeterDuniho "Initialized" 如中,如果我设置了 Hint 属性,比方说“搜索”,来自设计器,它应该在 InitializeComponent() 之后具有值“搜索”,但是它是空的。文本,即使我已经从设计器中设置了它的值,在 InitializeComponent() 之后仍然在构造函数中保留“”。
-
@PeterDuniho 为什么我需要发布 InitializeComponent() 的内容?它由 Visual Studio 自动生成。我应该再发 100 行吗?
标签: c# winforms custom-controls windows-forms-designer