TextChanged
немного запаздывает, возникает после того, как текст элемента управления был изменен и приводит к неловкому взаимодействию с пользователем.
Для лучшего взаимодействия с пользователем лучше обрабатывать WM_PASTE
сообщение и удалите запрещенные символы и вставьте проверенный тест на SelectedText
.TextChanged
Событие немного запоздало, и пользовательский интерфейс недостаточно дружелюбен, он удаляет символ после изменения свойства текста, что раздражает.Обрабатывая WM_PASTE
и OnKeyPress
, вы всегда можете держать каретку в ожидаемой пользователем позиции, очищать ввод без каких-либо мерцаний.
Вот пример, который допускает буквенно-цифровые символы и подчеркивание для TextBox
.При нажатии клавиши, если символ не разрешен, он воспроизводит звуковой сигнал.При вставке, если строка содержит запрещенные символы, она удаляет символы и вставляет только допустимые символы:
using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Windows.Forms;
public class MyTextBox : TextBox
{
private const int WM_PASTE = 0x0302;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool MessageBeep(int type);
protected override void WndProc(ref Message m)
{
if (m.Msg != WM_PASTE) { base.WndProc(ref m); }
else
{
var text = SanitizeText(Clipboard.GetText());
SelectedText = text;
}
}
protected virtual string SanitizeText(string value)
{
return Regex.Replace(value ?? "", @"[^a-zA-Z0-9_]", "");
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
var input = e.KeyChar;
var allowedChars = new char[] { '_', '\b' };
if (((ModifierKeys & (Keys.Control | Keys.Alt)) != 0) |
Char.IsLetterOrDigit(e.KeyChar) |
allowedChars.Contains(input))
{
base.OnKeyPress(e);
}
else
{
e.Handled = true;
MessageBeep(0);
}
}
}