我想知道是否有一种方法可以使catch语句清除导致错误的文本框。到目前为止,这是我的验证码:
private bool ValidateForm()
{
int val1, direction = 0;
double speed = 0.0;
bool validated = false;
if (txtName.Text != "")
{
try
{
// attempts to convert values into their primary data types.
// Any errors will throw an exception that will be reported
// as invalid data
val1 = Convert.ToInt32(txtXPos.Text);
val1 = Convert.ToInt32(txtYPos.Text);
speed = Convert.ToDouble(txtSpeed.Text);
direction = Convert.ToInt32(txtDirection.Text);
validated = true;
}
catch
{
MessageBox.Show(
"You have an invalid value entered. Please check your entry.",
"Invalid Values", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
if (speed < 0.0 || speed > (double)newAirplane.PlanePosition.MaxSpeed)
{
MessageBox.Show(
"Speed entered is out of range.",
"Invalid Values", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
if (direction < 0 || direction > 359)
{
MessageBox.Show(
"Direction is out of range",
"Invalid values", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
MessageBox.Show(
"Please enter a name.",
"Blank Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return validated;
}
答案 0 :(得分:2)
您可以在try块之外声明一个变量:
TextBox lastTextBox = null;
然后在每次转换之前,将其设置为您将从中获取值的文本框,如下所示:
lastTextBox = txtXPos;
val1 = Convert.ToInt32(txtXPos.Text);
然后在你的catch区块中:
if (lastTextBox != null)
lastTextBox.Text = "";
答案 1 :(得分:2)
假设这是Winforms,最好的办法是使用内置的ErrorProvider,而不是尝试使用自己的验证框架。
答案 2 :(得分:1)
我建议您使用Int32.TryParse Method和Double.TryParse
而不是“Try Catch”块答案 3 :(得分:1)
这里需要注意的重点是,您在非特殊情况下使用例外情况。也就是说,输入无效数字的用户并不例外 - 这几乎是预期的!
您应该使用TryParse
方法:
bool xValValid = Int32.TryParse(txtXPos.Text, out val1);
if(!xValValid){
txtXPos.Text = "";
validated = false;
MessageBox.Show("You have an invalid value entered. Please check your entry.", "Invalid Values", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
答案 4 :(得分:1)
您还可以将单个文本框的逻辑提取为:
private bool Validated<T>(Control tb, out T value)
{
try
{
value = return (T)Convert.ChangeType(tb.Text, typeof(T));
return true;
}
catch
{
value = default(T);
tb.Text = "";
return false;
}
}
你可以简单地用作:
if (!Validated<int>(txtXPos, out val1) ||
!Validated<int>(txtYPos, out val2) ||
!Validated<double>(txtSpeed, out speed) ||
!Validated<int>(txtDirection, out direction))
{
MessageBox.Show("Validation failed");
}
<强> [编辑] 强>
此外,从可用性的角度来看,清除文本框是一个坏主意,尤其是在TextChanged
事件中。如果我不小心在里面输入一个字母,我不希望我的文本框被清除。更好的方法是使用ErrorProvider,或以其他方式不引人注意地指出输入是错误的。
<强> [EDIT2] 强>
使用Convert.ChangeType可以从字符串转换为基本类型,但是如果需要将更复杂的字符串解析为自己的类,则可以提供任何您喜欢的转换方法:
private bool Validated<T>(Control tb, Func<string, T> converter, out T value)
{
try
{
value = converter(tb.Text);
return true;
}
catch
{
value = default(T);
tb.Text = "";
return false;
}
}
然后像这样使用它:
if (!Validated<int>(txtXPos, Convert.ToInt32, out val1) ||
!Validated<int>(txtYPos, Convert.ToInt32, out val2) ||
!Validated<double>(txtSpeed, Convert.ToDouble, out speed) ||
!Validated<int>(txtDirection, Convert.ToInt32, out direction))
{
MessageBox.Show("Validation failed");
}
通过这种方式,您可以传递任何具有签名Func<string, T>
的委托,该签名将执行实际转换,或者如果失败则抛出异常。
答案 5 :(得分:0)
我建议制作一个像
这样的功能private bool TryReadClear(TextBox txtBox, out double value)
{
if (double.TryParse(txtBox.Text, out value))
{
txtBox.BackColor = Color.White;
return true;
}
else
{
txtBox.BackColor = Color.Red;
txtBox.Text = string.Empty;
return false;
}
}
然后用这个简化的代码替换你的try / catch块:
validated = validated && TryReadClear(txtXPos, out val1);
validated = validated && TryReadClear(txtYPos, out val1);
validated = validated && TryReadClear(txtSpeed, out speed);
validated = validated && TryReadClear(txtDirection, out direction);
if (!validated)
{
MessageBox.Show("You have an invalid value entered. Please check your entry.", "Invalid Values", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
此方法的好处是,它会检查每次通过的所有文本框,并清除所有无效文本框。使用@ cdhowie的解决方案只会清除第一次失败,而不是全部。
编辑:您甚至可以做一些很酷的事情,比如将背景颜色设置为红色以直观地突出显示不良文本框(编辑上面的代码以显示示例)。
答案 6 :(得分:0)
private bool ValidateForm()
{
int val1, direction = 0;
double speed = 0.0;
bool validated;
if (txtName.Text != "")
{
try
{
//attempts to convert values into their primary data types. Any errors will throw an exception that will be reported as invalid data
int counter = 1;
val1 = Convert.ToInt32(txtXPos.Text);
counter = counter + 1;
val1 = Convert.ToInt32(txtYPos.Text);
counter = counter + 1;
speed = Convert.ToDouble(txtSpeed.Text);
counter = counter + 1;
direction = Convert.ToInt32(txtDirection.Text);
validated = true;
}
catch
{
switch(counter)
case 1:
txtXPos.Text="";
break;
case 2:
txtYPos.Text="";
break;
case 3:
txtSpeed.Text="";
break;
case 4:
txtDirection.Text="";
break;
default:
break;
MessageBox.Show("You have an invalid value entered. Please check your entry.", "Invalid Values", MessageBoxButtons.OK, MessageBoxIcon.Error);
validated = false;
}
if (speed < 0.0 || speed > (double)newAirplane.PlanePosition.MaxSpeed)
{
MessageBox.Show("Speed entered is out of range.", "Invalid Values", MessageBoxButtons.OK, MessageBoxIcon.Error);
validated = false;
}
if (direction < 0 || direction > 359)
MessageBox.Show("Direction is out of range", "Invalid values", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
MessageBox.Show("Please enter a name.", "Blank Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
validated = false;
}
return validated;
}
认为这是你所期待的。