如何在自定义文本框中处理验证
How to Handle validation within a custom TextBox
我有一个自定义文本框来处理测量值(英尺、英寸、毫米),它有几个依赖属性,这些属性决定了当框失去焦点时框的格式应该是什么。我得到了 OnLostFocus
函数中发生的所有转换,因为转换中间输入不起作用。在 OnLostFocus
中,我根据其他一些 DP 属性将值转换为数字并设置测量值 属性。这一切都很好。
我的问题是,如何处理验证?当有人输入无效值时,我希望文本框变红,就像您可以使用具有 ValidatesOnExceptions=true
的绑定一样。我在 OnLostfocus
的 catch 块中尝试了类似下面的内容
protected override void OnLostFocus(RoutedEventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(Text))
{
Text = "0";
}
if (IsMetric)
{
var measurement = convertStuffHere();
Text = measurement.Text;
Measurement = measurement.Value;
}
else
{
var measurement = convertOtherStuffHere();
// convert and formatting stuff here...
Text = measurement.Text;
Measurement = measurement.Value;
}
var binding = this.GetBindingExpression(TextBox.TextProperty);
if (binding != null)
Validation.ClearInvalid(this.GetBindingExpression(TextBox.TextProperty));
}
catch (Exception)
{
var rule = new DataErrorValidationRule();
var binding = this.GetBindingExpression(TextBox.TextProperty);
if (binding != null)
{
ValidationError validationError = new ValidationError(rule, this.GetBindingExpression(TextBox.TextProperty));
validationError.ErrorContent = "This is not a valid input";
Validation.MarkInvalid(this.GetBindingExpression(TextBox.TextProperty), validationError);
}
}
finally
{
base.OnLostFocus(e);
}
}
这几乎可以工作,但验证错误出现较晚。在文本框周围出现红色框之前,我必须失去焦点、获得焦点并再次失去焦点。
我用起来像<myns:MeasurementTextBox Text="{Binding MeasurementText1, ValidatesOnExceptions=True}" Margin="10" IsMetric="True"></myns:MeasurementTextBox>
您可以使用 TextBoxBase.TextChanged 事件代替 UIElement.LostFocus。
我有一个自定义文本框来处理测量值(英尺、英寸、毫米),它有几个依赖属性,这些属性决定了当框失去焦点时框的格式应该是什么。我得到了 OnLostFocus
函数中发生的所有转换,因为转换中间输入不起作用。在 OnLostFocus
中,我根据其他一些 DP 属性将值转换为数字并设置测量值 属性。这一切都很好。
我的问题是,如何处理验证?当有人输入无效值时,我希望文本框变红,就像您可以使用具有 ValidatesOnExceptions=true
的绑定一样。我在 OnLostfocus
protected override void OnLostFocus(RoutedEventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(Text))
{
Text = "0";
}
if (IsMetric)
{
var measurement = convertStuffHere();
Text = measurement.Text;
Measurement = measurement.Value;
}
else
{
var measurement = convertOtherStuffHere();
// convert and formatting stuff here...
Text = measurement.Text;
Measurement = measurement.Value;
}
var binding = this.GetBindingExpression(TextBox.TextProperty);
if (binding != null)
Validation.ClearInvalid(this.GetBindingExpression(TextBox.TextProperty));
}
catch (Exception)
{
var rule = new DataErrorValidationRule();
var binding = this.GetBindingExpression(TextBox.TextProperty);
if (binding != null)
{
ValidationError validationError = new ValidationError(rule, this.GetBindingExpression(TextBox.TextProperty));
validationError.ErrorContent = "This is not a valid input";
Validation.MarkInvalid(this.GetBindingExpression(TextBox.TextProperty), validationError);
}
}
finally
{
base.OnLostFocus(e);
}
}
这几乎可以工作,但验证错误出现较晚。在文本框周围出现红色框之前,我必须失去焦点、获得焦点并再次失去焦点。
我用起来像<myns:MeasurementTextBox Text="{Binding MeasurementText1, ValidatesOnExceptions=True}" Margin="10" IsMetric="True"></myns:MeasurementTextBox>
您可以使用 TextBoxBase.TextChanged 事件代替 UIElement.LostFocus。