Подтвердить что ты не робот

Вставить событие в текстовом поле WPF

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

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

Каков наилучший способ захватить вложенный текст в TextBox?

Кроме того, у меня проблема при нажатии на обратное пространство, я не могу понять, какое событие это будет срабатывать. OnPreviewTextInput не запускается!

Любые идеи по захвату вложенных текстовых и обратных пространственных событий в WPF TextBox?

4b9b3361

Ответ 1

Вот какой код я лежал на случай, если мне это когда-либо понадобится. Могу вам помочь.

public Window1()
{
    InitializeComponent();

    // "tb" is a TextBox
    DataObject.AddPastingHandler(tb, OnPaste);
}

private void OnPaste(object sender, DataObjectPastingEventArgs e)
{
    var isText = e.SourceDataObject.GetDataPresent(DataFormats.UnicodeText, true);
    if (!isText) return;

    var text = e.SourceDataObject.GetData(DataFormats.UnicodeText) as string;
    ...
}

Ответ 2

Проблема с попыткой перехвата и захвата всех отдельных событий, которые могут привести к изменению свойства TextBox.Text, заключается в том, что таких событий много:

  • TextInput: типы пользователей
  • KeyDown: Удалить, Backspace, Enter, IME
  • Жесты команд: Ctrl-X, Ctrl-Y, Ctrl-V, Ctrl-X
  • MouseDown: кнопка вставки, кнопка выключения, кнопка отмены,...
  • Нажмите: пробел, нажатый, когда кнопки "Вставить, вырезать", "Отменить" имеют локальную фокусировку.
  • RaiseEvent: код вызывает команды Paste, Cut, Undo, Redo
  • Accessiblity: голосовые команды, клавиатура Брайля и т.д.

Попытка надежно перехватить все это упражнение в бесполезности. Гораздо лучшее решение - контролировать TextBox.TextChanged и отклонять изменения, которые вам не нравятся.

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

Например, в вашем случае вы можете реализовать свойство RestrictValidChars, аналогичное свойству RestrictDeleteTo в этом коде. Это будет одно и то же, за исключением того, что внутренний цикл проверяет вставки, а не удаляет. Он будет использоваться следующим образом:

<TextBox my:TextBoxRestriction.RestrictValidChars="0123456789" />

Это просто идея о том, как это можно обработать. Существует много способов структурирования вашего кода в зависимости от того, что вы хотите. Например, вы можете изменить TextBoxRestriction, чтобы вызвать свой собственный код для проверки с помощью присоединенного свойства, которое принимает делегат или объект, содержащий событие.

Подробнее о том, как привязать свойство Text, когда вы используете класс TextBoxRestriction, см. в другом ответе, чтобы он не вызывал ограничение, если вы этого не хотите.

Ответ 3

Для backspace, пожалуйста, проверьте PreviewKeyDown событие

Для команды paste добавьте привязку команды к ApplicationCommands.Paste и установите аргумент для обработки, если вы ничего не хотите с ним делать:

<Window.CommandBindings>
  <CommandBinding Command="ApplicationCommands.Paste"
                  Executed="PasteExecuted" />
</Window.CommandBindings>

И в коде позади:

private void PasteExecuted(object sender, ExecutedRoutedEventArgs e)
{
    e.Handled = true;
}

Ответ 4

Вы можете достичь этого с событием PreviewKeyDown и событием TextChanged.

В PreviewKeyDown захватить операцию Вставить

if(Key.V == e.Key && Keyboard.Modifiers == ModifierKeys.Control)
{
   strPreviousString = this.txtNumber.Text;
   bIsPasteOperation = true;
}

В TextChanged событие

if (true == bIsPasteOperation)
{

   if (false == this.IsNumber(this.txtNumber.Text))
   {
      this.txtNumber.Text = strPreviousString;
      e.Handled = true;
   }
   bIsPasteOperation = false;
}

Где метод IsNumber проверяет введенный текст Number или not

private bool IsNumber(string text)
{
   int number;

   //Allowing only numbers
   if (!(int.TryParse(text, out number)))
   {
      return false;
   }
   return true
}