Разрешить только буквенно-цифровой в текстовом поле

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

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

  1. A-Z
  2. а-я
  3. 0-9
  4. Космос

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

вопрос задан 26.05.2009
Sauron
7790 репутация

13 ответов


  • 31 рейтинг

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

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

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

    ответ дан MusiGenesis, с репутацией 60340, 26.05.2009
  • 11 рейтинг

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

    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.

    ответ дан WhoIsRich, с репутацией 2963, 13.03.2014
  • 9 рейтинг

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

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

    Обновление: теперь, когда вы указываете, это 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.

    ответ дан Gishu, с репутацией 99101, 26.05.2009
  • 3 рейтинг

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

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

    ответ дан Szymon Rozga, с репутацией 15399, 26.05.2009
  • 3 рейтинг

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

    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;
            }
        }
    }
    
    ответ дан shane, с репутацией 173, 30.01.2013
  • 3 рейтинг

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

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

    Код для настраиваемого DP выглядит следующим образом:

    // When set to a Regex, the TextBox will only accept characters that match the RegEx
    
    /// 
    /// Lets you enter a RegexPattern of what characters are allowed as input in a TextBox ///
     
    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;
            }
        }
    }
    

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

    
    
    ответ дан Rachel, с репутацией 92992, 13.03.2014
  • 2 рейтинг
    private void _txtPath_KeyDown(object sender, KeyEventArgs e)
      {
         if ((e.Key < Key.A) || (e.Key > Key.Z))
            e.Handled = true;
      }
    
    ответ дан does_not_exist, с репутацией , 28.07.2009
  • 2 рейтинг

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

    http: // wpftoolkit. CodePlex. ком / вики страницы? title = MaskedTextBox & ReferringTitle = Home

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

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

    ответ дан gr-eg, с репутацией 166, 14.10.2011
  • 2 рейтинг

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

    ответ дан GWLlosa, с репутацией 14708, 26.05.2009
  • 1 рейтинг

    только алфавитно-цифровой 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;
      }
    }
    
    ответ дан miguel, с репутацией 11, 7.12.2011
  • 1 рейтинг

    и ваш regExp может выглядеть как [0-9a-zA-Z] *, чтобы разрешить только английские буквенно-цифровые символы

    ответ дан Rune FS, с репутацией 18108, 26.05.2009
  • 0 рейтинг

    Используйте Asp. NET AJAX Control Toolkit

    <%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
    

    и использовать FilteredTextBoxExtender

    
    
    
    
    ответ дан Mr. P, с репутацией 2251, 5.04.2014
  • 0 рейтинг

    по моему. Net Framework 4. Приложение 5 C #

        private void txtRF_Register_Val_KeyDown(object sender, KeyEventArgs e)
        {
            //only enable alphanumeric
            if (!(((e.KeyCode < Keys.NumPad0) || (e.KeyCode > Keys.NumPad9)) && ((e.KeyCode < Keys.A) || (e.KeyCode > Keys.E))))
            {
                e.SuppressKeyPress = false;
            }
            else
            {
                e.SuppressKeyPress = true;
            }
        }
    
    ответ дан Vincent Vrignaud, с репутацией 1, 24.06.2015