字母数字文本框 - Validate/Sanitize 粘贴前的剪贴板文本

Alphanumeric Textbox - Validate/Sanitize clipboard text before paste

我的 Textbox 使用 Keypressed 事件只接受字母数字字符和下划线,但是当我右键单击文本框并粘贴特殊字符并接受它时我遇到了问题

有没有办法在单击粘贴之前从那里验证字符串?

任何答案都会有所帮助,谢谢!

你可以

1- 禁用文本框的快捷方式,这将禁用 Ctrl-C、Ctrl-V 和第二行(将分配一个空的上下文菜单,没有项目并将覆盖原始上下文菜单)并且没有上下文菜单将出现(因为它没有项目):

textBox1.ShortcutsEnabled = false;
textBox1.ContextMenu = new ContextMenu();

2-如果您不想禁用粘贴选项,您可以使用文本框的 TextChanged 事件并在那里验证粘贴的文本。

TextChanged 有点晚,它在控件文本更改后引发,导致用户体验不佳。

为了获得更好的用户体验,最好处理 WM_PASTE 消息并删除不允许的字符并将经过清理的测试粘贴到 SelectedTextTextChanged 事件有点晚,用户体验不够友好,它会在文本 属性 更改后删除字符,这很烦人。通过处理 WM_PASTEOnKeyPress,您可以始终将插入符号保持在用户期望的位置,在没有任何闪烁的情况下清理输入。

字母数字文本框

这是一个示例,它允许 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);
        }
    }
}