我想过滤用户输入的数据。我只是希望他能够添加数字,或者。并在发生错误时删除。
我有这段代码:
private void textBox_KeyPress(object sender, KeyPressEventArgs e)
{
if ((char.IsDigit(e.KeyChar) == false) &&
(e.KeyChar != '\b') && (e.KeyChar != ','))
e.Handled = true;
if (e.KeyChar == ',' && (sender as TextBox).Text.IndexOf(',') > 0)
e.Handled = true;
}
现在我有两个问题:
1)我有两个文本框(用户应该写一些将被添加/分割的数字等字段),当我在其中一个中只写一个逗号时会出现错误。
2)我也希望能够使用“。”,但我希望它变成“,”。
答案 0 :(得分:1)
这是我编写的代码,使用WndProc
尽可能优先拦截事件,下面的代码处理,添加按键,以编程方式粘贴和设置文本。
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace NetTools.GUI
{
public class FastTextBox : TextBox
{
[DebuggerHidden, DebuggerNonUserCode, DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string hint = string.Empty;
/// <summary>
/// Is called in preview the system handle the changes, and determines whether the text will be accepted and handled by the system.
/// </summary>
/// <param name="oldText">The old text.</param>
/// <param name="newText">The current text (included the newer changes).</param>
/// <param name="input">The newer changes.</param>
/// <param name="offset">Start position of changes.</param>
/// <param name="length">Length of <paramref name="input"/>.</param>
/// <returns>Whether the system can handle the text.</returns>
public delegate bool TextAcceptorEventHandler(string oldText, string newText, string input, int offset, int length);
/// <summary>
/// Is called in preview of or after the system handle the changes.
/// </summary>
/// <param name="oldText">The old text.</param>
/// <param name="newText">The current text (included the newer changes).</param>
/// <param name="input">The newer changes.</param>
/// <param name="offset">Start position of changes.</param>
/// <param name="length">Length of <paramref name="input"/>.</param>
public delegate void TextEventHandler(string oldText, string newText, string input, int offset, int length);
/// <summary>
/// Is called in preview of the system handle the changes.
/// </summary>
public event TextEventHandler PreviewTextChange = null;
/// <summary>
/// Is called after the system handled the changes.
/// </summary>
public event TextEventHandler AfterTextChange = null;
public string Hint
{
[DebuggerHidden]
get
{
return hint;
}
[DebuggerHidden]
set
{
if (value == hint)
return;
hint = value;
SendMessage(Handle, 0x1501, 1, value);
}
}
public TextAcceptorEventHandler TextAcceptor
{
[DebuggerHidden]
get;
[DebuggerHidden]
set;
}
[DebuggerHidden]
protected override void CreateHandle()
{
base.CreateHandle();
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.FixedWidth | ControlStyles.FixedHeight | ControlStyles.Opaque, DoubleBuffered = true);
}
/// <summary>
/// Is called in preview of a text change, before the system handles it, and determines whether the text will be accepted and handled by system.
/// </summary>
/// <param name="oldText">The last written text.</param>
/// <param name="newText">The current text (included the newer changes).</param>
/// <param name="input">The newer changes.</param>
/// <param name="offset">Start position of changes.</param>
/// <param name="length">Length of <paramref name="input"/>.</param>
/// <returns></returns>
[DebuggerHidden]
protected virtual bool OnAcceptTextInput(string oldText, string newText, string input, int offset, int length)
{
return TextAcceptor == null ? true : TextAcceptor.Invoke(oldText, newText, input, offset, length);
}
/// <summary>
/// Is called in preview of a text change, before the system handles it.
/// </summary>
/// <param name="oldText">The last written text.</param>
/// <param name="newText">The current text (included the newer changes).</param>
/// <param name="input">The newer changes.</param>
/// <param name="offset">Start position of changes.</param>
/// <param name="length">Length of <paramref name="input"/>.</param>
[DebuggerHidden]
protected virtual void OnPreviewTextChange(string oldText, string newText, string input, int offset, int length)
{
if (PreviewTextChange != null)
PreviewTextChange.Invoke(oldText, newText, input, offset, length);
}
/// <summary>
/// Is called after the system handled the changes.
/// </summary>
/// <param name="oldText">The old text.</param>
/// <param name="newText">The current text (included the newer changes).</param>
/// <param name="input">The newer changes.</param>
/// <param name="offset">Start position of changes.</param>
/// <param name="length">Length of <paramref name="input"/>.</param>
[DebuggerHidden]
protected virtual void OnAfterTextChange(string oldText, string newText, string input, int offset, int length)
{
if (AfterTextChange != null)
AfterTextChange.Invoke(oldText, newText, input, offset, length);
}
[DebuggerHidden]
private bool CallbackPreview(string oldText, string newText, string input, int offset, int length)
{
if (string.IsNullOrEmpty(newText) ? true : OnAcceptTextInput(oldText, newText, input, offset, length))
{
OnPreviewTextChange(oldText, newText, input, offset, length);
return true;
}
return false;
}
[DebuggerHidden]
private bool CallbackPreview(ref string newText, string oldText, string input, int offset, int length)
{
newText = GetNewText(oldText, input, offset, length);
return CallbackPreview(oldText, newText, input, offset, length);
}
[DebuggerHidden]
private string GetNewText(string oldText, string input, int offset, int length)
{
if (input.Length == 1 ? input.ToCharArray()[0] == (int)Keys.Back : false)
return Text.Length > 0 ? $"{oldText.Substring(0, offset - (length == 0 ? 1 : 0))}{oldText.Substring(offset + length)}" : string.Empty;
else
return $"{(offset > 0 ? oldText.Substring(0, offset) : string.Empty)}{input}{(offset == oldText.Length - 1 ? string.Empty : oldText.Substring(offset + length))}";
}
[DebuggerHidden]
protected override void WndProc(ref Message m)
{
string text = "";
switch (m.Msg)
{
case 0x102:
int code = m.WParam.ToInt32();
if (code == 22 && ModifierKeys.HasFlag(Keys.Control))
goto case 0x302;
text = ((char)code).ToString();
goto case 0xC;
case 0x302:
text = Clipboard.GetText();
goto case 0xC;
case 0xC:
string input = string.Empty, newText = string.Empty;
if (string.IsNullOrEmpty(text))
{
newText = Marshal.PtrToStringUni(m.LParam);
if (CallbackPreview(Text, newText, string.Empty, SelectionStart, SelectionLength))
base.WndProc(ref m);
} else
{
input = text;
if (CallbackPreview(ref newText, Text, input, SelectionStart, SelectionLength))
base.WndProc(ref m);
}
OnAfterTextChange(Text, newText, input, SelectionStart, SelectionLength);
break;
default:
base.WndProc(ref m);
break;
}
}
}
}
然后,您可以使用FastTextBox
作为控件,代替TextBox
,并以编程方式将TextAcceptor
属性设置为委托:
yourFastTextBox.TextAcceptor = yourTextAcceptorDelegate;
private bool CidrTextAcceptor(string oldText, string newText, string input, int offset, int length)
{
return whether the text can be wrote or not.
}
有关其他说明,请参阅我在课堂上写的文档。
修改强> 我根据剪贴板的错误改进了代码。
答案 1 :(得分:0)
此代码允许使用逗号:
private void textBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsDigit(e.KeyChar) && e.KeyChar != ',' && e.KeyChar != '.')
{
e.Handled = true;
}
else if (e.KeyChar == '.')
{
e.KeyChar = ',';
}
}
但是,查看代码时,您似乎只想允许一个逗号。此代码将内容限制为仅包含一个逗号:
private void textBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsDigit(e.KeyChar) && e.KeyChar != ',' && e.KeyChar != '.')
{
e.Handled = true;
}
else if (e.KeyChar == '.')
{
e.KeyChar = ',';
}
if (e.KeyChar == ',')
{
//can use .Contains, indexOf, etc. I used count incase you want more than 1
if(((TextBox) sender).Text.Count(s=>s==',') == 1)
{
e.Handled = true;
}
}
}
显然,我不知道如何在评论中格式化代码,因此我更新主要答案以满足额外要求。 此代码将允许 - 但无论何时按下它都将其置于数字的开头:
if (!char.IsDigit(e.KeyChar) && e.KeyChar != ',' && e.KeyChar != '.' && e.KeyChar != '-')
{
e.Handled = true;
}
else if (e.KeyChar == '.')
{
e.KeyChar = ',';
}
else if (e.KeyChar == '-')
{
if (((TextBox) sender).Text.Contains("-"))
{
e.Handled = true;
}
else
{
((TextBox) sender).Text = "-" + ((TextBox) sender).Text;
e.Handled = true;
}
}
if (e.KeyChar == ',')
{
if(((TextBox) sender).Text.Count(s=>s==',') == 1)
{
e.Handled = true;
}
}
答案 2 :(得分:0)
您可以使用regex
+ text changed event
。在你的情况下,它非常简单:
static string regexPattern = "[^0-9.,]";
Regex regex = new Regex(regexPattern);
private void myTextBox_TextChanged(object sender, EventArgs e)
{
myTextBox.Text = regex.Replace(myTextBox.Text, "").Replace(".", ",");
}
答案 3 :(得分:0)
您是否考虑在aspx页面中使用Regular expression validator
和textbox
?
<asp:TextBox ID="txtDevice" runat="server" Text="sample"></asp:TextBox>
<asp:RegularExpressionValidator ID="revDeviceTextBnd" Text="*" Display="Dynamic" runat="server" ControlToValidate="txtDevice" ValidationExpression="Your regex goes here" ValidationGroup="onBnd" >
</asp:RegularExpressionValidator>
这只是另一种方法。