C# 向windows窗体控件组添加行为
我试图模拟在文本框上有一个标签的web功能,该标签显示文本框应该包含的值的类型。我可以单独添加事件,但我想知道是否有办法将“行为”添加到一组控件中 请参见示例代码:C# 向windows窗体控件组添加行为,c#,winforms,controls,C#,Winforms,Controls,我试图模拟在文本框上有一个标签的web功能,该标签显示文本框应该包含的值的类型。我可以单独添加事件,但我想知道是否有办法将“行为”添加到一组控件中 请参见示例代码: private void labelFirstName_Click(object sender, EventArgs e) { HideLabelFocusTextBox(labelFirstName, textBoxFirstName); } private void HideLabelFocusTextBox(Labe
private void labelFirstName_Click(object sender, EventArgs e)
{
HideLabelFocusTextBox(labelFirstName, textBoxFirstName);
}
private void HideLabelFocusTextBox(Label LabelToHide, TextBox TextBoxToShow)
{
LabelToHide.Visible = false;
TextBoxToShow.Focus();
}
private void textBoxFirstName_Leave(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(textBoxFirstName.Text))
labelFirstName.Visible = true;
}
private void textBoxFirstName_Enter(object sender, EventArgs e)
{
labelFirstName.Visible = false;
}
您始终可以创建一个用户控件来执行此操作。将文本框和标签都放在控件内,并在用户控件内对逻辑进行编码。这样,该控件的每个实例的行为都相同。您可以将文本框控件子类化(编写您自己的继承文本框的子类) 顺便说一句,我已经考虑过这一点,我会采取另一种方法: 我将重写文本框的绘制处理程序,当文本框不包含任何信息时,在其中绘制一个信息字符串 比如:
using System;
using System.Windows.Forms;
using System.Drawing;
class MyTextBox : TextBox
{
public MyTextBox()
{
SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
if (string.IsNullOrEmpty(this.Text))
{
e.Graphics.DrawString("My info string...", this.Font, System.Drawing.Brushes.Gray, new System.Drawing.PointF(0, 0));
}
else
{
e.Graphics.DrawString(Text, this.Font, new SolidBrush(this.ForeColor) , new System.Drawing.PointF(0, 0));
}
}
protected override void OnTextChanged(EventArgs e)
{
Invalidate();
base.OnTextChanged(e);
}
}
领带行为
您可以使用将功能/行为与TextBox控件联系得更近。这个简单的解决方案可能会让它感觉更紧密:
// NOTE: first parameter "this TextBox thisText"- these are all extension methods.
static public void AssignLabel(this TextBox thisText, Label companionLabel) {
thisText.Tag = companionLabel;
// HOOK UP EVENT AT THIS POINT, WHEN LABEL IS ASSIGNED (.NET 3.x)
thisText.Leave += (Object sender, EventArgs e) => {
LeaveMe(thisText); // Invoke method below.
};
}
static public void FocusText(this TextBox thisText) {
if (! ReferenceEquals(null, thisText.Tag))
(Label)thisText.Tag).Visible = false;
thisText.Focus();
}
static public void LeaveMe(this TextBox thisText) {
if (String.IsNullOrEmpty(thisText.Text))
((Label)thisText.Tag).Visible = true;
}
//etc.
然后使用文本框实例,如下所示:
Label overlay1 = new Label(); // Place these appropriately
Label overlay2 = new Label(); // on top of the text boxes.
Label overlay3 = new Label();
TextBox myTextbox1 = new TextBox();
TextBox myTextbox2 = new TextBox();
TextBox myTextbox3 = new TextBox();
// Note: Calling our extension methods directly on the textboxes.
myTextbox1.AssignLabel(overlay1);
myTextbox1.FocusText();
myTextbox1.LeaveMe();
myTextbox2.AssignLabel(overlay2);
myTextbox2.FocusText();
myTextbox2.LeaveMe();
myTextbox3.AssignLabel(overlay3);
myTextbox3.FocusText();
myTextbox3.LeaveMe();
//etc...
工作原理
代码更清晰,适用于您实例化的所有文本框
它依赖于TextBox类的来将标签引用存储到中(这样每个TextBox都知道它的标签),并且还引入了.NET 3.x,它允许我们将方法“附加”到TextBox类本身,从而将您的行为直接绑定到它
我用你的代码制作了几乎相同的东西,通过调整将其转化为扩展方法,并将标签与文本框相关联
变异
如果要将同一方法附加到其他控件(而不仅仅是文本框),请扩展基类本身,如下所示:
static public void LeaveMe(this Control thisControl) { //...
另一种选择可能是使用。这些基本上允许您在设计时向任何控件添加行为(尽管如果我没记错的话,这些行为可能会受到限制)。工具提示是一个扩展程序提供程序的示例,它已经在框架中浮动。我曾经多次使用它们来做一些事情,比如添加对从资源文件获取控件文本值的支持。我将对常规文本框进行子类化,并添加属性,这些属性允许您查找相关标签或直接设置对相关标签的引用
通常在winform项目中,在将控件添加到窗体之前,我会对所有控件进行子类化,这样我就可以非常轻松地添加常用功能,而不必在将来更改窗体。我考虑过这一点,但我不想担心控件的大小和功能。您是否只是通过编程将标签添加到类中的文本框中?如果是这样,您如何将其映射到文本框的字体大小和类型。@克里斯:没错。你可以通过编程来完成。您可以查询文本框的公共属性,并将它们直接分配给任何其他属性,例如:MyLabel.Font=MyTextBox.Font@克里斯:看看新的代码示例。它很简单,只是有点古怪,但它展示了这个想法。我提到的绘图怪癖通过将控件上的字体设置为Microsoft Sans Serif,10pt,Bold来缓解。。。哈哈,现在是2010年。。。GDI+已经存在了一段时间,而旧的Win32积垢仍在浮出水面!(用.NET4.0运行VS2010…)伙计,有这么多好的答案。我喜欢这个,因为它的简单和重量(它很轻)。这有点笨重,但可以解决。我想这只适用于运行时创建的控件?我按照示例在设计图面上使用控件,没有生成错误,但没有任何事件对控件起作用。扩展方法将扩展该类型的所有控件(在本例中为TextBox类),无论它们是在设计图面上创建的还是您自己实例化的。方法不会在设计时显示,尽管属性会显示。(哦…刚刚意识到你说了一些事情!…必须调查一下…)好的。。。将事件添加到示例代码中,这样无论何时使用
AssignLabel(…)
扩展方法,它都会自动连接。我几乎选择了你的方法,我非常喜欢它,你是一个伟大的文档编制者。这个问题没有一个答案,这个答案写得最好,值得特别赞扬