WPF:TextBox控件禁用中文输入

需求:

TextBox控件只允许输入数字或英文字母

分析:

不允许中文输入:可以通过禁用输入法实现
InputMethod.IsInputMethodEnabled="False"
只允许数字或英文字母输入:可以在PreviewTextInput事件中通过正则表达式匹配进而过滤掉非法输入

正则表达式不熟练的可以参考:正则表达式30分钟入门教程 该博客中还提供了一个:Regester - 正则表达式测试工具

private void text_str_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
    // 匹配非英文字母和数字
    Regex regex = new Regex(@"[^a-z0-9A-Z]+");
    // 根据匹配结果 设置Handled属性 (true--表示事件已处理,输入中断)
    bool isMatch = regex.IsMatch(e.Text);
    e.Handled = isMatch;
}
由于"空格"未被输入事件捕捉:可以在PreviewKeyDown事件中判断空格键
private void text_str_PreviewKeyDown(object sender, KeyEventArgs e)
{
    // 按下空格键时,使输入中断
    if (e.Key==Key.Space)
    {
        e.Handled = true;
    }
}
最后要考虑"粘贴":以上操作并不能过滤掉粘贴中文和非法字符,所以可以在TextChanged事件中进行处理
private void text_str_TextChanged(object sender, TextChangedEventArgs e)
{
    var textBox = sender as TextBox;
    TextChange[] changes = new TextChange[e.Changes.Count];
    e.Changes.CopyTo(changes, 0);
    // 引起Text改变的字符串的起点
    int offset = changes[0].Offset;
    // 引起Text改变的字符串的长度
    if (changes[0].AddedLength > 0)
    {
        Regex regex = new Regex(@"[^a-z0-9A-Z]+");
        bool isMatch = regex.IsMatch(textBox.Text);
        // 最新的Text中若含有非法字符
        if (isMatch)
        {
            // 由于我们已经从键盘输入事件中屏蔽了非法字符;所以基本可以断定此非法输入是由于"粘贴"引起的
            textBox.Text = textBox.Text.Remove(offset, changes[0].AddedLength);
            // 控制光标位置,使其还能定位到变动前的位置
            textBox.SelectionStart = offset;
        }
    }
}

实现:

XAML布局文件
<Grid>
    <TextBox
        Width="200"
        FontSize="30"
        VerticalAlignment="Center"
        HorizontalAlignment="Center"
        InputMethod.IsInputMethodEnabled="False"
        PreviewKeyDown="TextBox_PreviewKeyDown"
        PreviewTextInput="TextBox_PreviewTextInput"
        TextChanged="TextBox_TextChanged"/>
</Grid>
对应事件处理方法
public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
    }

    private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        // 按下空格键时,使输入中断
        if (e.Key == Key.Space)
        {
            e.Handled = true;
        }
    }

    private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
    {
        // 匹配非英文字母和数字
        Regex regex = new Regex(@"[^a-z0-9A-Z]+");
        // 根据匹配结果 设置Handled属性 (true--表示事件已处理,输入中断)
        bool isMatch = regex.IsMatch(e.Text);
        e.Handled = isMatch;
    }

    private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        var textBox = sender as TextBox;
        TextChange[] changes = new TextChange[e.Changes.Count];
        e.Changes.CopyTo(changes, 0);
        // 引起Text改变的字符串的起点
        int offset = changes[0].Offset;
        // 引起Text改变的字符串的长度
        if (changes[0].AddedLength > 0)
        {
            Regex regex = new Regex(@"[^a-z0-9A-Z]+");
            bool isMatch = regex.IsMatch(textBox.Text);
            // 最新的Text中若含有非法字符
            if (isMatch)
            {
                // 由于我们已经从键盘输入事件中屏蔽了非法字符;所以基本可以断定此非法输入是由于"粘贴"引起的
                textBox.Text = textBox.Text.Remove(offset, changes[0].AddedLength);
                // 控制光标位置,使其还能定位到变动前的位置
                textBox.SelectionStart = offset;
            }
        }
    }
}
运行效果

WPF:TextBox控件禁用中文输入

WPF:TextBox控件禁用中文输入

上一篇:环境系列——window10家庭版基于docker安装kafka集群


下一篇:定位元素的父(parent::)、兄弟(following-sibling::、preceding-sibling::)节点