Silverlight Преобразование PlatformKeyCode в код символа - PullRequest
2 голосов
/ 29 января 2010

Вопрос:

Есть ли в Silverlight хороший способ перехватывать нежелательные символы, вводимые в текстовое поле?

Справочная информация:

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

  • '?'
  • '\'
  • '<' </li>
  • '>'

Хотя класс Silverlight TextBox не поддерживает событие KeyPress, у него есть событие KeyDown и KeyUp, которое можно использовать для получения информации о символах при вводе ключа в текстовое поле. Он выставляет их как член перечисления Key или может возвращать int для PlatformKeyCode .

Конечно, диапазон клавиш больше / отличается от диапазона символов - например, «F keys». Однако наличие чего-то вроде события KeyPress в Windows Forms свидетельствует о полезности возможности извлечения информации о конкретных символах.

Чтобы доказать, что все работает, я жестко закодировал значения PlatformKeyCode для нежелательных символов для моей платформы в обработчик событий, и все заработало ... но конечно это просто моя платформа. Мне нужно убедиться, что эта реализация не зависит от платформы. Вот код, демонстрирующий, как я бы хотел, чтобы он работал:

    private void theText_KeyDown(object sender, KeyEventArgs e)
    {
        int[] illegals = { 191, 188, 190, 220, 186, 222, 191, 56, 186};
        if (illegals.Any(i => i == e.PlatformKeyCode)) e.Handled = true;
    }

Ответы [ 2 ]

2 голосов
/ 25 марта 2011
using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;

public class FilterTextBoxBehavior : Behavior<TextBox>
{
    public readonly static DependencyProperty AllowAlphaCharactersProperty = DependencyProperty.Register("AllowAlphaCharacters", typeof(bool), typeof(FilterTextBoxBehavior), new PropertyMetadata(true));
    public bool AllowAlphaCharacters
    {
        get { return (bool)GetValue(AllowAlphaCharactersProperty); }
        set { SetValue(AllowAlphaCharactersProperty, value); }
    }

    public readonly static DependencyProperty AllowNumericCharactersProperty = DependencyProperty.Register("AllowNumericCharacters", typeof(bool), typeof(FilterTextBoxBehavior), new PropertyMetadata(true));
    public bool AllowNumericCharacters
    {
        get { return (bool)GetValue(AllowNumericCharactersProperty); }
        set { SetValue(AllowNumericCharactersProperty, value); }
    }

    public readonly static DependencyProperty AllowSpecialCharactersProperty = DependencyProperty.Register("AllowSpecialCharacters", typeof(bool), typeof(FilterTextBoxBehavior), new PropertyMetadata(true));
    public bool AllowSpecialCharacters
    {
        get { return (bool)GetValue(AllowSpecialCharactersProperty); }
        set { SetValue(AllowSpecialCharactersProperty, value); }
    }

    public readonly static DependencyProperty DoNotFilterProperty = DependencyProperty.Register("DoNotFilter", typeof(string), typeof(FilterTextBoxBehavior), new PropertyMetadata(default(string)));
    public string DoNotFilter
    {
        get { return (string)GetValue(DoNotFilterProperty); }
        set { SetValue(DoNotFilterProperty, value); }
    }

    protected override void OnAttached()
    {
        base.OnAttached();
        if (AssociatedObject == null) { return; }

        FilterAssociatedObject();
        AssociatedObject.TextChanged += OnTextChanged;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        if (AssociatedObject == null) { return; }

        FilterAssociatedObject();
        AssociatedObject.TextChanged -= OnTextChanged;
    }

    private void OnTextChanged(object sender, TextChangedEventArgs e) { FilterAssociatedObject(); }
    private void FilterAssociatedObject()
    {
        int cursorLocation = AssociatedObject.SelectionStart;

        for (int i = AssociatedObject.Text.Length - 1; i >= 0; i--)
        {
            char c = AssociatedObject.Text[i];
            if (ValidChar(c)) { continue; }

            AssociatedObject.Text = AssociatedObject.Text.Remove(i, 1);
            cursorLocation--;
        }

        AssociatedObject.SelectionStart = Math.Min(AssociatedObject.Text.Length, Math.Max(0, cursorLocation));
    }

    private bool ValidChar(char c)
    {
        if (!string.IsNullOrEmpty(DoNotFilter) && DoNotFilter.Contains(c)) { return true; }
        if (!AllowAlphaCharacters && char.IsLetter(c)) { return false; }
        if (!AllowNumericCharacters && char.IsNumber(c)) { return false; }
        if (!AllowSpecialCharacters && Regex.IsMatch(c.ToString(), @"[\W|_]")) { return false; }

        return true;
    }
}
2 голосов
/ 01 февраля 2010

Оба ответа (в комментариях) от Хенрик и Йоханнес содержат лучший ответ для сценария. Вместо того, чтобы думать, как программист Windows Forms, и записывать конкретное ключевое событие, канонический подход в Silverlight заключается в использовании события TextChanged для удаления нежелательных символов из TextBox. аналогичный вопрос о разрешении только числового ввода в TextBox - вот что подсказало используемое решение.

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

    private void fileNameTextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        string illegalChars = @"?<>:""\/*|";
        fileNameTextBox.Text = String.Join("", fileNameTextBox.Text.Split(illegalChars.ToCharArray()));
        fileNameTextBox.SelectionStart = fileNameTextBox.Text.Length;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...