У меня есть TextBox, который я использую на странице настроек своего приложения. Теперь это текстовое поле должно принимать/отображать только цифры. Однако существует несколько примеров и решений этой проблемы, но ни одно из них не работает для WinUI 3, так как они в основном появились 5-10 лет назад.
KeyPress событие не существует в WinUI 3 TextBox. При поиске альтернатив я увидел событие KeyDown, однако аргументы этого события другие и KeyRoutedEventArgs не содержат никаких свойств, подобных KeyChar.
Пример кода, который я нашел, применим для приложений WPF:
private void txtbox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
{
e.Handled = true;
}
}
Как добиться такого поведения в WinUI 3 TextBox?





Вы можете использовать InputScope!
Вы можете найти ссылку в документации Microsoft.
Вот пример от Microsoft:
<TextBox Header = "Telephone Number" InputScope = "TelephoneNumber"/>
Вы также можете выполнить дополнительные проверки в коде программной части, прослушивая событие TextChanged:
<TextBox TextChanged = "OnTextChanged" />
<!-- In your code-behind file -->
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
// Get the current text of the TextBox
var text = ((TextBox)sender).Text;
// Use a regular expression to only allow numeric values
var regex = new Regex("^[0-9]*$");
// If the text does not match the regular expression, undo the change
if (!regex.IsMatch(text))
{
((TextBox)sender).Undo();
}
}
Редактировать:
В WinUI 3 вы также можете использовать событие KeyDown.
Это очень похоже на то, как вы это делали в WPF:
<TextBox KeyDown = "OnKeyDown" />
private void OnKeyDown(object sender, KeyRoutedEventArgs e)
{
// Check if the key pressed is a numeric key
if (!((e.Key >= VirtualKey.Number0 && e.Key <= VirtualKey.Number9) || (e.Key >= VirtualKey.NumberPad0 && e.Key <= VirtualKey.NumberPad9)))
{
// If the key is not numeric, cancel the event and prevent the key from being entered
e.Handled = true;
}
}
Спасибо за ответ. Пара вещей; Я установил InputScope на Digits, однако я все еще могу вводить буквы и символы, кроме цифр. После этого я попробовал ваше событие, однако это полностью удаляет поле, если введена нецифра. Если это первый символ, это нормально, однако, если, скажем, 124552a, он удаляет все содержимое, как это можно изменить, чтобы удалялся только последний введенный символ?
Привет Линк! Я только что попробовал ваш код события KeyDown, однако это не имело никакого эффекта (даже не удалял символы или эффект на поле), i.imgur.com/Ovn4ZOf.png
Обновлять. Теперь я использую событие TextChanging, которое происходит синхронно перед визуализацией текста. Это помогает с UX. Я работаю над исправлением проблемы «удаление всего текста вместо последней записи».
Ответ @Link Hylia был каким-то образом правильным для достижения запрошенного поведения. Я расширил это, на что ответил:
KeyDown или TextChanged были асинхронными событиями и не блокировали отображение введенного ввода на экране. Я изменил это на событие TextChanging, которое запускается синхронно и до рендеринга TextBox.Text. Используя этот метод, я могу контролировать текст до его рендеринга и улучшать UX.TextBox.Код можно найти ниже:
private void textBox1_TextChanging(TextBox sender, TextBoxTextChangingEventArgs args)
{
var currentPosition = textBox1.SelectionStart - 1;
var text = ((TextBox)sender).Text;
var regex = new Regex("^[0-9]*$");
if (!regex.IsMatch(text))
{
var foundChar = Regex.Match(textBox1.Text, @"[^0-9]");
if (foundChar.Success)
{
textBox1.Text = textBox1.Text.Remove(foundChar.Index, 1);
}
textBox1.Select(currentPosition, 0);
}
}
Да, это обходной путь. отличная работа.
Ближайшим, вероятно, является NumberBox learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/… вы по-прежнему можете вводить недопустимые символы, но они будут удалены при смене фокуса. Исходник (WinUI2.8) находится здесь github.com/microsoft/microsoft-ui-xaml/tree/main/dev/NumberBox