добавить поведение в группу элементов управления окнами - PullRequest
2 голосов
/ 19 июня 2010

Я пытаюсь имитировать веб-функциональность наличия надписи над текстовым полем, которая показывает тип значения, которое текстовое поле должно содержать.Я могу добавить события по отдельности, но мне интересно, есть ли способ добавить «Поведение» в набор элементов управления.

Пожалуйста, посмотрите пример кода:

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;
}

Ответы [ 5 ]

2 голосов
/ 19 июня 2010

Вы можете создать подкласс для элемента управления текстового поля (напишите свой собственный, который наследует текстовое поле)

Кстати, я думал об этом, и я бы взял другой подход:

Я бы переопределил обработчик рисования текстового поля, и когда текстовое поле не содержит информации, нарисуйте в нем информационную строку.

Что-то вроде:

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);
    }
}
2 голосов
/ 19 июня 2010

Поведение галстука

Вы можете привязать функцию / поведение ближе к элементу управления 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...

Как это работает

Код чище и применяется ко всем текстовым полям, которые вы создаете .

Он использует свойство .Tag класса TextBox для хранения ссылки Label (поэтому каждый TextBox знает свою метку), а также методы расширения , представленные в .NET. 3.x, которые позволяют нам «прикреплять» методы к самому классу TextBox, чтобы привязать к нему ваше поведение.

Я взял ваш код и произвел почти то же самое с настройками, чтобы превратить его в методы расширения и связать метку с вашим текстовым полем.

Изменение

Если вы хотите присоединить тот же метод к другим элементам управления (а не только к текстовому полю), тогда расширьте базовый элемент управления на сам класс, например:

static public void LeaveMe(this Control thisControl) { //...
1 голос
/ 19 июня 2010

Я бы разделил обычное текстовое поле на подклассы и добавил бы свойства, которые позволят вам либо найти связанную метку, либо установить ссылку на соответствующую метку напрямую.

Как правило, в проектах winform я делю все элементы управления на подклассы, прежде чем добавлять их в свои формы, поэтому я могу очень легко добавлять общие функции без необходимости изменять формы в будущем.

1 голос
/ 19 июня 2010

Другим вариантом может быть использование Extender Provider .Они в основном позволяют добавлять поведение к любому элементу управления (хотя их можно ограничить, если я правильно помню) во время разработки.Всплывающая подсказка является примером поставщика расширений, который уже используется в рамках.Я использовал их довольно давно, чтобы сделать что-то вроде добавления поддержки для получения текстовых значений элементов управления из файла ресурсов.

1 голос
/ 19 июня 2010

Вы всегда можете создать пользовательский элемент управления, который делает это. Поместите и TextBox, и Label внутри элемента управления и закодируйте логику внутри элемента управления. Таким образом, каждый экземпляр этого элемента управления будет вести себя одинаково.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...