如何:实现绑定验证

本示例演示如何基于自定义验证规则,使用 ErrorTemplate 和样式触发器来提供视觉反馈,以便在输入无效值时向用户发出通知。

示例

下面示例中的 TextBox 的文本内容绑定到名为 ods 的绑定源对象的 Age 属性(类型为 int)。 该绑定设置为使用名为 AgeRangeRule 的验证规则,以便当用户输入了非数值字符或输入的值小于 21 或者大于 130 时,文本框旁边将显示一个红色感叹号,并且当用户将鼠标移动到该文本框上时,将显示包含错误消息的工具提示。

<TextBox Name="textBox1" Width="50" FontSize="15"
         Validation.ErrorTemplate="{StaticResource validationTemplate}"
         Style="{StaticResource textBoxInError}"
         Grid.Row="1" Grid.Column="1" Margin="2">
  <TextBox.Text>
    <Binding Path="Age" Source="{StaticResource ods}"
             UpdateSourceTrigger="PropertyChanged" >
      <Binding.ValidationRules>
        <local:AgeRangeRule Min="21" Max="130"/>
      </Binding.ValidationRules>
    </Binding>
  </TextBox.Text>
</TextBox>

下面示例演示 AgeRangeRule(从 ValidationRule 中继承并重写 Validate 方法)的实现。 对值调用 Int32.Parse 方法,以确保该值不包含任何无效字符。 Validate 方法返回 ValidationResult,该结果基于分析期间是否引发了异常以及生存期值是否超出了上界和下界,指示该值是否有效。

public class AgeRangeRule : ValidationRule
{
    public int Min { get; set; }
    public int Max { get; set; }

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        int age = 0;

        try
        {
            if (((string)value).Length > 0)
                age = int.Parse((String)value);
        }
        catch (Exception e)
        {
            return new ValidationResult(false, $"Illegal characters or {e.Message}");
        }

        if ((age < Min) || (age > Max))
        {
            return new ValidationResult(false,
              $"Please enter an age in the range: {Min}-{Max}.");
        }
        return ValidationResult.ValidResult;
    }
}
Public Class AgeRangeRule
    Inherits ValidationRule

    ' Properties
    Public Property Max As Integer
    Public Property Min As Integer
        
    ' Methods
    Public Overrides Function Validate(value As Object, cultureInfo As CultureInfo) As ValidationResult
        Dim num1 As Integer = 0
        Try 
            If (CStr(value).Length > 0) Then
                num1 = Integer.Parse(CStr(value))
            End If
        Catch exception1 As Exception
            Return New ValidationResult(False, $"Illegal characters or {exception1.Message}")
        End Try
        If ((num1 < Min) OrElse (num1 > Max)) Then
            Return New ValidationResult(False, $"Please enter an age in the range: {Min}-{Max}.")
        End If
        Return ValidationResult.ValidResult
    End Function

End Class

下面的示例演示了自定义的 ControlTemplate validationTemplate,它用于创建一个红色感叹号,以通知用户验证错误。 控件模板用于重新定义控件的外观。

<ControlTemplate x:Key="validationTemplate">
  <DockPanel>
    <TextBlock Foreground="Red" FontSize="20">!</TextBlock>
    <AdornedElementPlaceholder/>
  </DockPanel>
</ControlTemplate>

如下面的示例中所示,显示错误消息的 ToolTip 使用名为 textBoxInError 的样式创建。 如果 HasError 的值为 true,则触发器将当前 TextBox 的工具提示设置为其首个验证错误。 将 RelativeSource 设置为 Self,并引用当前元素。

<Style x:Key="textBoxInError" TargetType="{x:Type TextBox}">
  <Style.Triggers>
    <Trigger Property="Validation.HasError" Value="true">
      <Setter Property="ToolTip"
              Value="{Binding RelativeSource={x:Static RelativeSource.Self},
                              Path=(Validation.Errors)[0].ErrorContent}"/>
    </Trigger>
  </Style.Triggers>
</Style>

数据对象

以下代码片段是前面的代码示例中使用的数据对象。 实例在 XAML 中创建为静态资源,其键为 ods

public class MyDataSource
{
    public MyDataSource()
    {
        Age = 0;
        Age2 = 0;
    }

    public int Age { get; set; }
    public int Age2 { get; set; }
    public int Age3 { get; set; }
}
Public Class MyDataSource
    Public Sub New()
        Me.Age = 0
        Me.Age2 = 0
    End Sub

    Public Property Age As Integer
    Public Property Age2 As Integer
    Public Property Age3 As Integer
End Class

完整示例

有关完整示例,请参阅绑定验证示例

请注意,如未提供自定义 ErrorTemplate,则当出现验证错误时,将显示默认错误模板来为用户提供视觉反馈。 有关详细信息,请参阅数据绑定概述中的“数据验证”。 另外,WPF 还提供了内置验证规则,该规则捕获在更新绑定源属性期间引发的异常。 有关详细信息,请参阅 ExceptionValidationRule

另请参阅