C# 防止通过复制粘贴在Usercontrol(文本框)上插入特殊字符
我必须验证Usercontrol(文本框)是否插入特殊字符。在按键事件中,我使用此代码来处理此问题 OnKeyPress覆盖:C# 防止通过复制粘贴在Usercontrol(文本框)上插入特殊字符,c#,winforms,copy-paste,C#,Winforms,Copy Paste,我必须验证Usercontrol(文本框)是否插入特殊字符。在按键事件中,我使用此代码来处理此问题 OnKeyPress覆盖: 按键时受保护的覆盖无效(按键事件参数e){ 按键(e); 方法预防(e); } MethodToPrevent函数: private void MethodToPrevent(按键eventargs e){ var regex=new regex(@“[^a-zA-Z0-9\s]”); if(regex.IsMatch(e.KeyChar.ToString()){ e
按键时受保护的覆盖无效(按键事件参数e){
按键(e);
方法预防(e);
}
MethodToPrevent函数:
private void MethodToPrevent(按键eventargs e){
var regex=new regex(@“[^a-zA-Z0-9\s]”);
if(regex.IsMatch(e.KeyChar.ToString()){
e、 已处理=正确;
}
}
现在这个工作很好。但如果用户复制粘贴带有特殊字符的字符串,则此操作无效。我怎么办
尝试
但无法在此处捕获发件人部分。实际上,您的代码阻止ctrl键,但不阻止鼠标右键单击并粘贴。也许您可以阻止鼠标右键单击,或者您可以使用TextChanged事件
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
base.OnKeyPress(e);
MethodToPrevent(e);
}
private void MethodToPrevent(KeyPressEventArgs e)
{
var regex = new Regex(@"[^a-zA-Z0-9\s]");
if (regex.IsMatch(e.KeyChar.ToString()))
{
e.Handled = true;
}
}
// If the user presses the wrong key, it is already blocked with the
//MethodToPrevent() before the TextChanged().
//it is only prevent mouse right click and paste
private void textBox1_TextChanged(object sender, EventArgs e)
{
var regex = new Regex(@"[^a-zA-Z0-9\s]");
if (regex.IsMatch(textBox1.Text.ToString()))
{
textBox1.Text = "";
}
}
由于您显然使用的是自定义控件(TextBox派生),因此有一些建议可用于处理用户粘贴操作和过滤控件中的文本编辑(过滤器部分就是您提供的,该部门需要做更多的工作才能做到这一点,而不仅仅是在错误处理方面) 此自定义控件向标准文本框添加了一些功能:
OnKeyPress
处理的字符,允许光标移动,删除退格(我已经将\b
添加到过滤器正则表达式中,我认为它丢失了)
UserPaste
属性的PasteAction
枚举,以3种不同的方式过滤事件,该属性定义了控件对粘贴操作的反应行为(根据需要修改):
:用户可以在文本框中粘贴任何内容允许
:用户只能粘贴正则表达式筛选器允许的内容,其余内容将被删除Partial
:用户不能粘贴任何内容禁止
WM_粘贴
,使用方法(使用TextDataFormat.UnicodeText
)过滤从剪贴板读取的文本,然后向编辑控件发送消息,以添加修改后的文本(对于用户来说,它显示为实际的粘贴操作)
► base.WndProc()
在任何情况下都不会被调用,剪贴板也不会被触动。→ 如果要通知用户所采取的操作,请不要在WndProc方法覆盖中显示MessageBox 注意:这是我已经发布的自定义控件的一个修改版本(还有一些其他可能很方便的方法),用于同样的事情。→ 如果这两个问题确实相关,请告诉我
可能尝试使用另一个事件???,但无法在此处捕获发送者部分。如果尝试使用
OnTextChanged()
,则“发送者”是您所在的类,因为它是一个方法重写,并且您必须位于派生类中?…因此,如果您得到一个不需要的字符,您将在其TextChanged事件处理程序中清除控件的整个文本?Sinatr在一条注释中发布了一个链接,指向禁用WM_粘贴的答案。它也可以用于其他用途,例如警告使用r它的粘贴包含不允许的字符。我只是想指定可以使用textchanged事件。此代码的高级版本是在textchanged事件运行时查找并删除不需要的字符。通常,您尝试不在其textchanged事件中更改控件的文本。或者删除整个文本(在TextChanged事件中),如果用户按错键。不确定此代码的高级版本是什么意思。不,如果用户按错键,则在TextChanged()之前,它已被MethodToPrevent()阻止。在这种操作中,其目的是防止内容发生,而不是在内容发生后尝试修补。因此,您要做的是,如果以任何方式输入了不允许的内容,则首先防止文本发生更改。+您假设正则表达式要输入的每个字符都会引发KeyPress事件此外,正如前面提到的,原则上,您应该尽量避免在TextChanged事件中更改控件的文本(是的,我知道,我已经说过了)。
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
base.OnKeyPress(e);
MethodToPrevent(e);
}
private void MethodToPrevent(KeyPressEventArgs e)
{
var regex = new Regex(@"[^a-zA-Z0-9\s]");
if (regex.IsMatch(e.KeyChar.ToString()))
{
e.Handled = true;
}
}
// If the user presses the wrong key, it is already blocked with the
//MethodToPrevent() before the TextChanged().
//it is only prevent mouse right click and paste
private void textBox1_TextChanged(object sender, EventArgs e)
{
var regex = new Regex(@"[^a-zA-Z0-9\s]");
if (regex.IsMatch(textBox1.Text.ToString()))
{
textBox1.Text = "";
}
}
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Windows.Forms;
[ToolboxItem(true)]
[DesignerCategory("Code")]
public class TextBoxEx : TextBox
{
private bool m_NumbersOnly = false;
private Regex regex = new Regex(@"[^a-zA-Z0-9\s\b]", RegexOptions.Compiled);
public TextBoxEx() { }
public enum PasteAction
{
Allow,
Disallow,
Partial
}
public PasteAction UserPaste { get; set; }
public override string Text {
get => base.Text;
set {
if (!base.Text.Equals(value)) {
base.Text = regex.Replace(value, "");
}
}
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
if (regex.IsMatch(e.KeyChar.ToString())) {
e.Handled = true;
}
base.OnKeyPress(e);
}
protected override CreateParams CreateParams
{
[SecurityPermission(SecurityAction.LinkDemand,
Flags = SecurityPermissionFlag.UnmanagedCode)]
get {
CreateParams cp = base.CreateParams;
if (m_NumbersOnly) {
cp.Style |= NativeMethods.ES_NUMBER;
}
else {
cp.Style &= ~NativeMethods.ES_NUMBER;
}
return cp;
}
}
protected override void WndProc(ref Message m)
{
switch (m.Msg) {
case NativeMethods.WM_PASTE:
switch (UserPaste) {
case PasteAction.Disallow:
return;
case PasteAction.Partial:
string text = Clipboard.GetText(TextDataFormat.UnicodeText);
text = regex.Replace(text, "");
NativeMethods.SendMessage(this.Handle, NativeMethods.EM_REPLACESEL, 1, text);
return;
case PasteAction.Allow:
break;
}
break;
}
base.WndProc(ref m);
}
private class NativeMethods
{
internal const int WM_PASTE = 0x0302;
internal const int ES_NUMBER = 0x2000;
internal const int EM_REPLACESEL = 0xC2;
[DllImport("User32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern int SendMessage(IntPtr hWnd, uint uMsg, int wParam, string lParam);
}
}