C#文本框中的负数
本文关键字:文本 | 更新日期: 2023-09-27 18:21:12
我已经完成了这里的问题,并找到了让文本框只接受开头有一个十进制和负号的数值的答案。
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && e.KeyChar != '.' && e.KeyChar != '-')
{
e.Handled = true;
}
// only allow one decimal point
if (e.KeyChar == '.' && (sender as TextBox).Text.IndexOf('.') > -1)
{
e.Handled = true;
}
if (e.KeyChar == '-' && (sender as TextBox).Text.Length > 0)
{
e.Handled = true;
}
然而,我确实有一个问题。假设用户键入一个数字:
123455789764
然后他意识到这个数字是负数。他回到开头,试图输入负号,却发现它不起作用。有没有办法解决这个问题,而不是让用户删除他键入的数字,添加负数,然后重新键入数字?
试试这个:
Regex reg = new Regex(@"^-?'d+[.]?'d*$");
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (char.IsControl(e.KeyChar)) return;
if (!reg.IsMatch(textBox1.Text.Insert(textBox1.SelectionStart, e.KeyChar.ToString()) + "1")) e.Handled = true;
}
对于keyboardP的建议,我添加此代码是为了完全防止非数字值,我认为您应该尝试TextBox.ShortcutsEnabled = false;
,因为我认为用户不需要任何形式的复制和粘贴数字数据。
Regex reg = new Regex(@"^-?'d+[.]?'d*$");
bool textChangedByKey;
string lastText;
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (char.IsControl(e.KeyChar)) return;
if (!reg.IsMatch(textBox1.Text.Insert(textBox1.SelectionStart, e.KeyChar.ToString()) + "1"))
{
e.Handled = true;
return;
}
textChangedByKey = true;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (!textChangedByKey)
{
if (!reg.IsMatch(textBox1.Text))
{
textBox1.Text = lastText;
return;
}
}
else textChangedByKey = false;
lastText = textBox1.Text;
}
我尝试过使用Undo()
方法来重置SelectedText
,但它有点糟糕,即使上面的方法也没有带来好的视觉效果(当你尝试将文本粘贴到数字文本框中时,你可以看到文本正在更改并恢复到有效值)。
- 仅当单击某些"确定"或"提交"按钮时才评估字符,而不是每次击键时
- 使用正则表达式检查整个文本的有效性,而不仅仅是键入的字符或
- 尝试使用
Int64.TryParse
将文本解析为long
,并计算调用的bool
结果 - 已经阅读了以上所有内容:为什么不简单地使用
NumericUpDown
控件
您可以检查光标位置,当光标不是开头或开头已经有"-"时丢弃"-",而不是检查字符串的长度(当它为非零时丢弃"-")。
但是,在提交过程中稍后进行整个检查,而不是吞下击键,可能会更好地使用用户体验。
我认为依赖文本框事件是解决问题的更好方法。在任何情况下,你都可以继续使用你的方法,并用事件来补充它,以解释标题"-"的问题。此代码删除文本框中的任何短划线,除非位于第一个位置:
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (textBox1.Text.Trim().Length > 0)
{
if (textBox1.Text.Contains("-") && (textBox1.Text.Substring(0, 1) != "-" || textBox1.Text.Split('-').Length > 2))
{
bool headingDash = false;
if (textBox1.Text.Substring(0, 1) == "-")
{
headingDash = true;
}
textBox1.Text = textBox1.Text.Replace("-", "");
if (headingDash)
{
textBox1.Text = "-" + textBox1.Text;
}
}
}
}
这对我有效(尽管您可能会考虑根据您想要如何处理十进制分隔符进行一些修改(因为数字格式取决于CurrentCulture设置)
这只接受数字,输入的长度和进一步的格式(例如,在十进制分隔符之前只允许一个数字)没有被处理,尽管我认为可以修改它。
public enum NumericTextBoxType { TDecimal = 1, TByte, TShort, TInt, TLong }
public class NumericTextBox : TextBox
{
#region ARRAYS
private static readonly Keys[] separators =
{
Keys.Decimal,
Keys.Oemcomma,
Keys.OemPeriod
};
private static readonly Keys[] allowed =
{
Keys.D1,
Keys.D2,
Keys.D3,
Keys.D4,
Keys.D5,
Keys.D6,
Keys.D7,
Keys.D8,
Keys.D9,
Keys.D0,
Keys.NumPad0,
Keys.NumPad1,
Keys.NumPad2,
Keys.NumPad3,
Keys.NumPad4,
Keys.NumPad5,
Keys.NumPad6,
Keys.NumPad7,
Keys.NumPad8,
Keys.NumPad9,
Keys.Decimal,
Keys.Oemcomma,
Keys.OemPeriod,
Keys.OemMinus,
Keys.Subtract,
Keys.Back,
Keys.Delete,
Keys.Tab,
Keys.Enter,
Keys.Up,
Keys.Down,
Keys.Left,
Keys.Right
};
private static readonly Keys[] intallowed =
{
Keys.D1,
Keys.D2,
Keys.D3,
Keys.D4,
Keys.D5,
Keys.D6,
Keys.D7,
Keys.D8,
Keys.D9,
Keys.D0,
Keys.NumPad0,
Keys.NumPad1,
Keys.NumPad2,
Keys.NumPad3,
Keys.NumPad4,
Keys.NumPad5,
Keys.NumPad6,
Keys.NumPad7,
Keys.NumPad8,
Keys.NumPad9,
Keys.OemMinus,
Keys.Subtract,
Keys.Back,
Keys.Delete,
Keys.Tab,
Keys.Enter,
Keys.Up,
Keys.Down,
Keys.Left,
Keys.Right
};
#endregion ARRAYS
#region PROPERTY NumericTextBoxType
private NumericTextBoxType _NumericTextBoxType = NumericTextBoxType.TDecimal;
public NumericTextBoxType NumericTextBoxType
{
get
{
return
_NumericTextBoxType;
}
set
{
_NumericTextBoxType = value;
}
}
#endregion PROPERTY NumericTextBoxType
#region PROPERTY AllowMinus
public bool AllowMinus { get; set; }
#endregion
string prvText = "";
int prevSelStart = 0;
public NumericTextBox()
: base()
{
this.NumericTextBoxType = NumericTextBoxType.TDecimal;
this.AllowMinus = true;
}
#region EVENT METHOD OnKeyDown
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.Modifiers == Keys.Control)
{
prvText = this.Text;
prevSelStart = this.SelectionStart;
return;
}
// ignore not allowed
if (NumericTextBoxType != NumericTextBoxType.TDecimal)
{
if (!intallowed.Contains(e.KeyCode)) e.SuppressKeyPress = true;
}
else
{
if (!allowed.Contains(e.KeyCode)) e.SuppressKeyPress = true;
else if (separators.Contains(e.KeyCode))
{
NumberFormatInfo numberFormatInfo = System.Globalization.CultureInfo.CurrentCulture.NumberFormat;
string decimalSeparator = numberFormatInfo.NumberDecimalSeparator;
int selLength = this.SelectionLength;
int selStart = this.SelectionStart;
if (!this.Text.Remove(selStart, selLength).Contains(decimalSeparator))
{
this.Text = this.Text
.Remove(selStart, selLength)
.Insert(this.SelectionStart, decimalSeparator);
this.SelectionStart = selStart + decimalSeparator.Length;
}
e.SuppressKeyPress = true;
}
}
// ignore minus if not first or not allowed
if (e.KeyCode == Keys.OemMinus || e.KeyCode == Keys.Subtract)
{
if (!this.AllowMinus) e.SuppressKeyPress = true;
else if (NumericTextBoxType == NumericTextBoxType.TByte) e.SuppressKeyPress = true;
else if (this.SelectionStart > 0) e.SuppressKeyPress = true;
}
prvText = this.Text;
prevSelStart = this.SelectionStart;
}
#endregion EVENT METHOD OnKeyDown
#region METHOD OnTextChanged
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
// don't allow incorrect paste operations
if (Regex.IsMatch(this.Text, (!AllowMinus ? "[-" : "[") + @"^'d.,]") ||
Regex.Matches(this.Text, @"[.,]").Count > 1)
{
this.Text = prvText;
this.SelectionStart = prevSelStart;
}
}
#endregion
}