У меня в форме есть TextBox, пользователь должен ввести туда какую-то строку.

После каждых 2 символов он должен автоматически добавлять туда "|". Но я не знаю, как это сделать. Вот мой код:

private void textBox1_TextChanged(object sender, EventArgs e)
{
    string input = textBox1.Text; int count = 0;
    foreach (char c in input)
    {
        count++;
        if (count == 2)
        {
            input += '|';
            count = 0;
            textBox1.Text = input;
        }
    }
}
  • Пользователь должен вводить символы только в шестнадцатеричном формате (то есть 0-9, a-f).

Я пробовал использовать e.Keychar для события Keypress, но он не работает, если пользователь использует Copy-Paste и Ctrl-C, Ctrl-V.

2
Minh Đức Lê 1 Мар 2015 в 16:40

4 ответа

Лучший ответ

Вы не должны обрабатывать событие TextChanged, если вам действительно не нужно, но вам следует полагаться на MaskedTextBox, который создан именно для этой цели.

Вы можете найти хорошее руководство здесь, на MSDN.

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


Практические инструкции:

Создайте элемент управления MaskedTextBox и установите маску на &&\|&&\|&&\|&&\|&& ('&' означает любой символ ASCII, повторяйте \|&& столько, сколько вам нужно). Затем создайте событие TextChanged и установите для обработчика события следующее:

void maskedTextBox1_TextChanged(object sender, System.EventArgs e)
{
    string input = this.maskedTextBox1.Text;

    StringBuilder outputBuilder = new StringBuilder(input.Length);
    char[] allowedCharacters = new char[] { '|', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

    foreach (char c in input)
    {
        if (allowedCharacters.Contains(c))
        {
            outputBuilder.Append(c);
        }
    }

    string output = outputBuilder.ToString();
    if (!input.Equals(output))
    {
        this.maskedTextBox1.Text = output;
    }
}
1
Patrick Hofman 1 Мар 2015 в 14:34

Избегайте нажатия клавиш CTRL.

if (e.Control == true)
{
    MessageBox.Show("Cut/Copy and Paste Options are disabled");
}
-1
Patrick Hofman 1 Мар 2015 в 13:48

Одна из проблем с вашим текущим кодом заключается в том, что событие изменения текста срабатывает даже при программном обновлении textBox. Один из способов избежать этого - определить, когда изменение текста вызвано вами. В приведенном ниже примере я сделал это, проверив "|" находится в пределах 2 символов от конца строки.

Используйте StringBuilder для постепенного создания строки, чтобы избежать создания нескольких объектов String.

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

  private void textBox1_TextChanged(object sender, EventArgs e)
  {
     string input = textBox1.Text;
     // did I cause this event to fire? if not, parse the input
     if (input.LastIndexOf("|") < input.Length - 2)
     {
        input = input.Replace("|", "");
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < input.Length; i++)
        {
           stringBuilder.Append(input[i]);
           if (i % 2 == 1)
           {
              stringBuilder.Append("|");
           }
        }
        textBox1.Text = stringBuilder.ToString();
        textBox1.Select(textBox1.Text.Length, 0);
     }
  }
0
chiaboy 1 Мар 2015 в 14:45

Алгоритмическое решение 1-й проблемы

Убедитесь, что индекс четный и> 0, и сдвиньте символы влево, чтобы освободить место для '|' персонаж.

for (int i=0; i<input.length; i++)
{
    var c = input[i];
    
    if (i % 2 == 0 && i>0)
    {
        
        for(int j=input.length-1; j>=i; j++) input[j+1] = input[j];
        input[i] = '|';
        textBox1.Text = input;
    }
}

Убедитесь, что у вас достаточно места для ввода (если это коллекция примитивных типов)

0
Community 20 Июн 2020 в 09:12