Разрешить только буквенно-цифровой в текстовом поле - PullRequest
16 голосов
/ 26 мая 2009

У меня есть текстовое поле, которое не должно вводить какие-либо специальные символы.

Пользователь может ввести:

  1. A-Z
  2. a-z
  3. 0-9
  4. Space

Как мне сделать событие KeyDown для этого?

Ответы [ 13 ]

31 голосов
/ 26 мая 2009

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

Несколько лучший способ - обработать событие TextChanged и удалить из него все оскорбительные символы. Это немного сложнее, так как вы должны отслеживать положение каретки и переустанавливать ее в соответствующем месте после изменения свойства Text поля.

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

18 голосов
/ 13 марта 2014

Просто хотел добавить код для тех, кто попал сюда при поиске:

private void Filter_TextChanged(object sender, EventArgs e)
{
    var textboxSender = (TextBox)sender;
    var cursorPosition = textboxSender.SelectionStart;
    textboxSender.Text = Regex.Replace(textboxSender.Text, "[^0-9a-zA-Z ]", "");
    textboxSender.SelectionStart = cursorPosition;
}

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

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

9 голосов
/ 26 мая 2009

Используйте регулярное выражение, чтобы отфильтровать других символов. Или используйте методы Char.IsDigit, IsXXX, чтобы отфильтровать нежелательные символы. Много способов сделать это.

Обновление: если вам необходимо использовать KeyDown, то, похоже, вам также нужно обработать KeyPressed и установить obEventArgs.Handled = true, чтобы запретить символы. См. Пример на странице KeyDown MSDN

Обновление: теперь, когда вы укажете, это WPF. Приведенный ниже код позволит вводить в текстовое поле только символы a-z и A-Z. Расширьте по мере необходимости ...

private void _txtPath_KeyDown(object sender, KeyEventArgs e)
      {
         if ((e.Key < Key.A) || (e.Key > Key.Z))
            e.Handled = true;
      }

Это сломается, если вы скопируете и вставите вещи в текстовое поле. Проверяйте весь текст, как только пользователь покидает элемент управления или когда он нажимает кнопку ОК / Отправить, как говорит MusicGenesis.

3 голосов
/ 13 марта 2014

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

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

Код для пользовательского DP выглядит так:

// When set to a Regex, the TextBox will only accept characters that match the RegEx

/// <summary>
/// Lets you enter a RegexPattern of what characters are allowed as input in a TextBox
/// </summary>
public static readonly DependencyProperty AllowedCharactersRegexProperty =
    DependencyProperty.RegisterAttached("AllowedCharactersRegex",
                                        typeof(string), typeof(TextBoxProperties),
                                        new UIPropertyMetadata(null, AllowedCharactersRegexChanged));

// Get
public static string GetAllowedCharactersRegex(DependencyObject obj)
{
    return (string)obj.GetValue(AllowedCharactersRegexProperty);
}

// Set
public static void SetAllowedCharactersRegex(DependencyObject obj, string value)
{
    obj.SetValue(AllowedCharactersRegexProperty, value);
}

// Events
public static void AllowedCharactersRegexChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    var tb = obj as TextBox;
    if (tb != null)
    {
        if (e.NewValue != null)
        {
            tb.PreviewTextInput += Textbox_PreviewTextChanged;
            DataObject.AddPastingHandler(tb, TextBox_OnPaste);
        }
        else
        {
            tb.PreviewTextInput -= Textbox_PreviewTextChanged;
            DataObject.RemovePastingHandler(tb, TextBox_OnPaste);
        }
    }
}

public static void TextBox_OnPaste(object sender, DataObjectPastingEventArgs e)
{
    var tb = sender as TextBox;

    bool isText = e.SourceDataObject.GetDataPresent(DataFormats.Text, true);
    if (!isText) return;

    var newText = e.SourceDataObject.GetData(DataFormats.Text) as string;
    string re = GetAllowedCharactersRegex(tb);
    re = string.Format("[^{0}]", re);

    if (Regex.IsMatch(newText.Trim(), re, RegexOptions.IgnoreCase))
    {
        e.CancelCommand();
    }
}

public static void Textbox_PreviewTextChanged(object sender, TextCompositionEventArgs e)
{
    var tb = sender as TextBox;
    if (tb != null)
    {
        string re = GetAllowedCharactersRegex(tb);
        re = string.Format("[^{0}]", re);

        if (Regex.IsMatch(e.Text, re, RegexOptions.IgnoreCase))
        {
            e.Handled = true;
        }
    }
}

И он используется так:

<TextBox Text="{Binding SomeValue, UpdateSourceTrigger=PropertyChanged}" 
         local:TextBoxHelpers.AllowedCharactersRegex="a-zA-Z0-9\s" />
3 голосов
/ 31 января 2013

Я столкнулся с этим в серебряном свете и написал что-то вроде этого.

private string _filterRegexPattern = "[^a-zA-Z0-9]"; // This would be "[^a-z0-9 ]" for this question.
private int _stringMaxLength = 24;


private void _inputTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    if (!string.IsNullOrEmpty(_filterRegexPattern))
    {
        var text = _inputTextBox.Text;
        var newText = Regex.Replace(_inputTextBox.Text, _filterRegexPattern, "");

        if (newText.Length > _stringMaxLength)
        {
            newText = newText.Substring(0, _stringMaxLength);
        }


        if (text.Length != newText.Length)
        {
            var selectionStart = _inputTextBox.SelectionStart - (text.Length - newText.Length);
            _inputTextBox.Text = newText;
            _inputTextBox.SelectionStart = selectionStart;
        }
    }
}
3 голосов
/ 26 мая 2009

Я думаю, стоит подумать о фильтрации по событию TextChanged в TextBox. Вы можете создать операцию, которая избавит вас от любых недопустимых символов в вашей текстовой строке. Это немного более грязно, чем блокировка события KeyDown.

Но я думаю, что это правильный путь, потому что вы не блокируете встроенные в WPF механизмы обработки событий KeyDown / Up, поэтому копирование / вставка все еще работает. Вы будете работать на более высоком уровне абстракций, поэтому я думаю, что будет легче выяснить, что происходит.

2 голосов
/ 14 октября 2011

Самый простой способ сделать это - включить расширенный инструментарий WPF, который имеет элемент управления для выполнения именно того, о чем вы просите, путем указания маски.

http://wpftoolkit.codeplex.com/wikipage?title=MaskedTextBox&referringTitle=Home

Он также будет отображать маску в текстовом поле при вводе, если требуется.

(также имеется много других полезных элементов управления)

2 голосов
/ 28 июля 2009
private void _txtPath_KeyDown(object sender, KeyEventArgs e)
  {
     if ((e.Key < Key.A) || (e.Key > Key.Z))
        e.Handled = true;
  }
2 голосов
/ 26 мая 2009

Я знаю, что в winForms есть элемент управления MaskedTextBox, который позволяет вам указывать именно такие вещи. Я не знаю WPF, поэтому я не знаю, есть ли он там, но если это так, сделайте это. Это НАМНОГО проще, чем все это с нажатиями клавиш и событиями, а также более надежно.

1 голос
/ 07 декабря 2011

только алфавитно-цифровой TextBox WPF C #,

извините за мой английский .. но с этим кодом для WPF, c # я разрешаю только буквенно-цифровой

private void txtTraslado_TextChanged(object sender, KeyEventArgs e)
{
  if (((e.Key < Key.NumPad0)||(e.Key > Key.NumPad9))&&((e.Key < Key.A)||(e.Key > Key.Z)))
  {
    e.Handled = true;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...