我正在尝试模仿在文本框上显示标签的Web功能,该文本框显示文本框应包含的值的类型。我可以单独添加事件,但我想知道是否有办法将“行为”添加到一组控件中。
请参阅示例代码:
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;
}
答案 0 :(得分:2)
您可以继承文本框控件(编写自己的文本框继承文本框)
是的,我已经考虑过这个问题,我会采取另一种方法:我会覆盖文本框的绘图处理程序,当文本框不包含任何信息时,将信息字符串绘制到其中。
类似的东西:
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);
}
}
答案 1 :(得分:2)
您可以使用extension methods将功能/行为更接近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类的.Tag property来存储Label引用(因此每个TextBox都知道它的标签),以及.NET 3.x中引入的extension methods允许我们“将”方法“附加”到TextBox类本身,以将您的行为直接绑定到它。
我接受了你的代码并通过调整生成了几乎相同的东西,将其转换为扩展方法,并将Label与文本框相关联。
如果要将相同的方法附加到其他控件(而不仅仅是文本框),请扩展基本Control类本身,如:
static public void LeaveMe(this Control thisControl) { //...
答案 2 :(得分:1)
您始终可以创建执行此操作的用户控件。将TextBox和Label放在控件中,并在用户控件内编写逻辑。这样,该控件的每个实例都会表现相同。
答案 3 :(得分:1)
另一种选择可能是使用Extender Provider。这些基本上允许您在设计时向任何控件添加行为(尽管如果我没记错,这些可能会受到限制)。 ToolTip是一个已在框架中浮动的Extender Provider的示例。我曾经多次使用这些来做一些事情,例如添加支持从资源文件中获取控件的文本值。
答案 4 :(得分:1)
我会将常规文本框子类化并添加属性,这些属性允许您查找关联的标签或直接设置对相关标签的引用。
通常在winform项目中,我在将所有控件添加到表单之前对其进行子类化,因此我可以非常轻松地添加常用功能,而无需在将来更改表单。