You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为System.Windows.Input.KeyEventArgs编写过滤器?修复C++类名输入校验问题

修复C# WPF TextBox的C++类名输入过滤问题

问题分析

你的代码失效原因在于仅通过Key枚举判断按键,却忽略了大量非法符号是通过Shift+数字/字母组合输入的(比如Shift+2输入@、Shift+3输入#),且原逻辑只处理了Shift+OemMinus(下划线)的合法情况,未拦截其他Shift组合的非法输入;同时完全没实现「首字符不能为数字」的规则。

修复方案

推荐改用PreviewTextInput事件直接处理输入的文本内容(比判断按键更可靠),同时结合DataObject.Pasting事件拦截非法粘贴操作,导航编辑键的功能会自动保留,无需额外处理。

完整修复代码

using Microsoft.VisualStudio.PlatformUI;
using System.Windows.Controls;
using System.Windows.Input;
using System.Text.RegularExpressions;

public partial class AddCppClassDialog : DialogWindow
{
    // 匹配合法C++类名的正则:首字符为字母/下划线,后续为字母/数字/下划线
    private readonly Regex _validCppClassNameRegex = new Regex(@"^[a-zA-Z_][a-zA-Z0-9_]*$");

    public AddCppClassDialog()
    {
        InitializeComponent();
        // 处理实时输入
        ClassNameTextBox.PreviewTextInput += ClassNameTextBox_PreviewTextInput;
        // 处理粘贴操作
        DataObject.AddPastingHandler(ClassNameTextBox, ClassNameTextBox_Pasting);
    }

    private void ClassNameTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
    {
        var textBox = sender as TextBox;
        if (textBox == null) return;

        // 模拟输入后的完整文本
        var newText = GetTextAfterInput(textBox, e.Text);

        // 验证是否符合规则,不符合则禁止输入
        if (!_validCppClassNameRegex.IsMatch(newText))
        {
            e.Handled = true;
        }
    }

    private void ClassNameTextBox_Pasting(object sender, DataObjectPastingEventArgs e)
    {
        var textBox = sender as TextBox;
        if (textBox == null || !e.DataObject.GetDataPresent(typeof(string)))
        {
            e.CancelCommand();
            return;
        }

        var pastedText = e.DataObject.GetData(typeof(string)) as string;
        var newText = GetTextAfterInput(textBox, pastedText);

        // 验证粘贴内容是否合法,非法则取消粘贴
        if (!_validCppClassNameRegex.IsMatch(newText))
        {
            e.CancelCommand();
        }
    }

    // 辅助方法:计算输入/粘贴后的完整文本
    private string GetTextAfterInput(TextBox textBox, string inputText)
    {
        var currentText = textBox.Text;
        if (textBox.SelectionLength > 0)
        {
            // 替换选中内容
            return currentText.Remove(textBox.SelectionStart, textBox.SelectionLength).Insert(textBox.SelectionStart, inputText);
        }
        else
        {
            // 在光标位置插入内容
            return currentText.Insert(textBox.CaretIndex, inputText);
        }
    }
}

方案优势

  1. 直接基于文本内容验证,规避了按键组合判断的遗漏问题,覆盖输入法输入、粘贴等所有输入场景。
  2. 正则表达式^[a-zA-Z_][a-zA-Z0-9_]*$严格符合C++类名的语法规则。
  3. Home、Delete、Back等导航编辑键不会触发PreviewTextInput事件,功能自动保留,无需额外逻辑处理。

内容的提问来源于stack exchange,提问作者qloq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 16:30:20