Реальная подсказка в текстовом поле Visual Studio C# [дубликат]


На этот вопрос уже есть ответ здесь:

В настоящее время я создаю приложение Windows Forms на Visual Studio в C# и пытаюсь найти способ получить реальную подсказку .

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

Я хочу серый текст, который вам не нужно отступать, чтобы ввести что-то там. Поэтому я хочу, чтобы он вел себя как HTML-заполнитель , как строка поиска "Search Q&A" при переполнении стека.

Есть ли простой способ сделать это, например, настроить свойство textbox в конструкторе Visual Studio?

5 2

5 ответов:

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

Этот следующий класс является просто расширением стандартного текстового поля

 class PHTextBox : System.Windows.Forms.TextBox
    {
        System.Drawing.Color DefaultColor; 
        public string PlaceHolderText {get;set;}
        public PHTextBox(string placeholdertext)
        {
            // get default color of text
           DefaultColor = this.ForeColor;
            // Add event handler for when the control gets focus
            this.GotFocus += (object sender, EventArgs e) => 
            {
                this.Text = String.Empty;
                this.ForeColor = DefaultColor;
            };

            // add event handling when focus is lost
            this.LostFocus += (Object sender, EventArgs e) => {
                if (String.IsNullOrEmpty(this.Text) || this.Text == PlaceHolderText)
                {
                    this.ForeColor = System.Drawing.Color.Gray;
                    this.Text = PlaceHolderText;
                }
                else
                {
                    this.ForeColor = DefaultColor;
                }
            };



            if (!string.IsNullOrEmpty(placeholdertext))
            {
                // change style   
                this.ForeColor = System.Drawing.Color.Gray;
                // Add text
                PlaceHolderText = placeholdertext;
                this.Text = placeholdertext;
            }



        }


    }

Скопируйте / вставьте в новый cs-файл под названиемPHTextBox .CS.

Перейдите к графическому дизайнеру и добавьте текстовое поле. Перейдите в конструктор и измените строку ввода для текстового поля следующим образом:

Введите описание изображения здесь

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

Введите описание изображения здесь

Вы пробовали наложить метку на текстовое поле?

В событии нажатия клавиши textbox можно проверить длину текстового поля.текст и установите метку.

О событии нажатия клавиши..

MyLabel.Visible = String.IsNullOrEmpty(MyTextBox.Text);

Конечно, вы можете установить текст метки по умолчанию, а также выделить его серым цветом.

Проблема с этим, если ваша форма является re sizable.

То, что вы хотите достичь, не является родным для windows forms.

А как насчет этого

    private bool hasTextBeenTyped;

    private void Form1_Load(object sender, EventArgs e)
    {
        this.ActiveControl = label1;
        textBox1.ForeColor = Color.LightGray;
    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        hasTextBeenTyped = !String.IsNullOrEmpty(textBox1.Text);

        if (hasTextBeenTyped)
        {
            textBox1.ForeColor = Color.Black;
        }
    }

    private void textBox1_Click(object sender, EventArgs e)
    {
        if (!hasTextBeenTyped)
        {
            textBox1.Text = "";
        }
    }

    private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        hasTextBeenTyped = true;
    }

Это.ActiveControl = label1; - это просто для того, чтобы изначально отвлечь внимание от текстового поля. Если что-то еще уже есть, не беспокойтесь об этой линии.

Пожалуйста, взгляните на мой ControlHintManager класс, ControlHintInfo тип и ControlHintType перечисление. Они написаны на английском языке. Vb.Net, но вы можете получить идею, анализируя исходный код, или скомпилировать библиотеку, чтобы использовать ее в своем проекте C# без каких-либо дополнительных усилий.

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

Использование так дружелюбно:

ControlHintInfo hint1 = 
    new ControlHintInfo("I'm a hint text.", font (or nul), Color.Gray, 
                        ControlHintType.Persistent);

ControlHintManager.SetHint(TextBox1, hint1);

Чтобы достичь этого самостоятельно, один из способов-вызов функции Win32 SendMessage с сообщением EM_ SETCUEBANNER, однако, это приведет к слишком простой подсказке с плохим поведением, не рекомендуется,

Таким образом, правильный способ достичь этого-взять под свой контроль текст edit-control самостоятельно, обрабатывая Control.HandleCreated, Control.Enter, Control.Leave, Control.MouseDown, Control.KeyDown и Control.Disposed события (как вы можете видеть в мой связанный исходный код).

Просто используйте объект для отслеживания состояния элемента управления (forecolor, text и, возможно, шрифт), а затем правильно используйте упомянутые обработчики событий для установки или восстановления текста и цвета.

Это онлайн-перевод на C# наиболее важного кода связанных URL-адресов, если это поможет вам лучше понять его:

private static void Control_HandleCreated(object sender, EventArgs e) {

    InstanceControlHintFields();

    Control ctrl = (Control)sender;
    ControlHintInfo hintInfo = controlHintsB(ctrl);

    SetProperties(ctrl, hintInfo);
}

private static void Control_Enter(object sender, EventArgs e) {

    InstanceControlHintFields();

    Control ctrl = (Control)sender;
    string ctrlText = ctrl.Text;
    ControlHintInfo ctrlDefaults = controlHintsDefaults(ctrl);
    ControlHintInfo hintInfo = controlHintsB(ctrl);

    switch (hintInfo.HintType) {

        case ControlHintType.Normal:
            if ((ctrlText.Equals(hintInfo.Text, StringComparison.OrdinalIgnoreCase))) {
                RestoreProperties(ctrl, ctrlDefaults);
            }

            break;
    }
}

private static void Control_Leave(object sender, EventArgs e) {

    InstanceControlHintFields();

    Control ctrl = (Control)sender;
    string ctrlText = ctrl.Text;
    ControlHintInfo ctrlDefaults = controlHintsDefaults(ctrl);
    ControlHintInfo hintInfo = controlHintsB(ctrl);

    switch (hintInfo.HintType) {

        case ControlHintType.Normal:
            if ((ctrlText.Equals(hintInfo.Text, StringComparison.OrdinalIgnoreCase))) {
                RestoreProperties(ctrl, ctrlDefaults);

            } else if (string.IsNullOrEmpty(ctrlText)) {
                SetProperties(ctrl, hintInfo);

            }

            break;
        case ControlHintType.Persistent:
            if (string.IsNullOrEmpty(ctrlText)) {
                SetProperties(ctrl, hintInfo);
            }

            break;
    }
}

private static void Control_MouseDown(object sender, MouseEventArgs e) {

    InstanceControlHintFields();

    Control ctrl = (Control)sender;
    string ctrlText = ctrl.Text;
    ControlHintInfo hintInfo = controlHintsB(ctrl);

    switch (hintInfo.HintType) {

        case ControlHintType.Persistent:


            if ((ctrlText.Equals(hintInfo.Text, StringComparison.OrdinalIgnoreCase))) {
                // Get the 'Select' control's method (if exist).
                MethodInfo method = sender.GetType.GetMethod("Select", BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, {
                    typeof(int),
                    typeof(int)
                }, null);

                if ((method != null)) {
                    // Select the zero length.
                    method.Invoke(ctrl, new object[] {
                        0,
                        0
                    });
                }

            }

            break;
    }
}

private static void Control_KeyDown(object sender, KeyEventArgs e) {

    Control ctrl = (Control)sender;
    string ctrlText = ctrl.Text;
    ControlHintInfo ctrlDefaults = controlHintsDefaults(ctrl);
    ControlHintInfo hintInfo = controlHintsB(ctrl);

    switch (hintInfo.HintType) {

        case ControlHintType.Persistent:
            if ((ctrlText.Equals(hintInfo.Text, StringComparison.OrdinalIgnoreCase))) {
                RestoreProperties(ctrl, ctrlDefaults);

            } else if (string.IsNullOrEmpty(ctrlText)) {
                RestoreProperties(ctrl, ctrlDefaults, skipProperties: { "Text" });

            }

            break;
        case ControlHintType.Normal:
            if (string.IsNullOrEmpty(ctrlText)) {
                RestoreProperties(ctrl, ctrlDefaults);
            }

            break;
    }
}

private static void Control_Disposed(object sender, EventArgs e) {
    RemoveHint((Control)sender);
}
PS: Этоотражение , основанное на поддержке большего разнообразия элементов управления.

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

1) создать а класс .cs файл, вызываемый, например, MyExtensions.cs, имеющий пространство имен вызывается, например, 'Extensions'.

2) создайте метод в TextBox, который называется Init (строка запроса) это займет текст подсказки вы хотите отобразить внутри TextBox.

3) позвольте мне прекратить говорить и дать вам остальную часть кода для MyExtensions.cs (весь код):

Мои экстензии.cs

using System.Drawing;
using System.Windows.Forms;

namespace Extensions
{
   public static class MyExtensions
{

    public static void Init(this TextBox textBox, string prompt)
    {
        textBox.Text = prompt;
        bool wma = true;
        textBox.ForeColor = Color.Gray;
        textBox.GotFocus += (source, ex) =>
        {
            if (((TextBox)source).ForeColor == Color.Black)
                return;
            if (wma)
            {
                wma = false;
                textBox.Text = "";
                textBox.ForeColor = Color.Black;
            }
        };

        textBox.LostFocus += (source, ex) =>
        {
            TextBox t = ((TextBox)source);
            if (t.Text.Length == 0)
            {
                t.Text = prompt;
                t.ForeColor = Color.Gray;
                return;
            }
            if (!wma && string.IsNullOrEmpty(textBox.Text))
            {
                wma = true;
                textBox.Text = prompt;
                textBox.ForeColor = Color.Gray;
            }
        };
        textBox.TextChanged += (source, ex) =>
        {
            if (((TextBox)source).Text.Length > 0)
            {
                textBox.ForeColor = Color.Black;
            }
        };
    }

}
}
Теперь предположим, что у вас есть три TextBox: tbUsername, tbPassword, tbConfirm:

В вашем методе Form_Load(object sender, EventArgs e) инициализируйте ваши три текстовых поля, чтобы они имели соответствующиетекстовые сообщения :

using Extensions;

namespace MyApp{

         public partial class Form1 : Form{

                private void Form1_Load(object sender, 
                                        EventArgs e){

                    tbUsername.Init("Type a username");
                    tbPassword.Init("Type a password");
                    tbConfirm.Init("Confirm your password");
                }
        }
}

Наслаждайтесь! :)