Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 向windows窗体控件组添加行为_C#_Winforms_Controls - Fatal编程技术网

C# 向windows窗体控件组添加行为

C# 向windows窗体控件组添加行为,c#,winforms,controls,C#,Winforms,Controls,我试图模拟在文本框上有一个标签的web功能,该标签显示文本框应该包含的值的类型。我可以单独添加事件,但我想知道是否有办法将“行为”添加到一组控件中 请参见示例代码: private void labelFirstName_Click(object sender, EventArgs e) { HideLabelFocusTextBox(labelFirstName, textBoxFirstName); } private void HideLabelFocusTextBox(Labe

我试图模拟在文本框上有一个标签的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;
}

您始终可以创建一个用户控件来执行此操作。将文本框和标签都放在控件内,并在用户控件内对逻辑进行编码。这样,该控件的每个实例的行为都相同。

您可以将文本框控件子类化(编写您自己的继承文本框的子类)

顺便说一句,我已经考虑过这一点,我会采取另一种方法:

我将重写文本框的绘制处理程序,当文本框不包含任何信息时,在其中绘制一个信息字符串

比如:

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(…)
扩展方法,它都会自动连接。我几乎选择了你的方法,我非常喜欢它,你是一个伟大的文档编制者。这个问题没有一个答案,这个答案写得最好,值得特别赞扬