入力データ検証 その6 カスタムValidationRule
その5ではIDataErrorInfoインターフェイス実装により発生するエラーをチェックするDataErrorValidationRuleをご紹介しました。既定で用意されているValidationRuleはExceptionValidationRuleとDataErrorValidationRuleの2つだけで、これらを使用する場合にはバインドしているソースオブジェクト側に検証ロジックを書くかたちになります。これら2つの方法以外に、ValidationRuleクラスを継承して、カスタムのValidationRuleを作成する方法があります。今回はそれをご紹介します。
ValidationRuleクラスは抽象クラスとなっており、実装が必要なメンバはValidateメソッドです。このメソッドでバインディングによって転送されてくる値を受け取り、検証を行い、その結果をValidationResultとして返します。
Window1.xaml
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ValidationSample"
Title="Window1" Height="300" Width="300" FontSize="32">
<Window.Resources>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel>
<TextBox Margin="30">
<TextBox.Text>
<Binding Path="ID">
<Binding.ValidationRules>
<local:IsPositiveIdValidation/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<Button Content="Button" Margin="30"/>
</StackPanel>
</Window>
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ValidationSample"
Title="Window1" Height="300" Width="300" FontSize="32">
<Window.Resources>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel>
<TextBox Margin="30">
<TextBox.Text>
<Binding Path="ID">
<Binding.ValidationRules>
<local:IsPositiveIdValidation/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<Button Content="Button" Margin="30"/>
</StackPanel>
</Window>
IsPositiveIdValidation.vb
Public Class IsPositiveIdValidation
Inherits ValidationRule
Public Overrides Function Validate(ByVal value As Object, ByVal cultureInfo As System.Globalization.CultureInfo) As System.Windows.Controls.ValidationResult
Dim result As Integer
If Not Integer.TryParse(CType(value, String), result) Then
Return New ValidationResult(False, "整数値を入力してください。")
ElseIf result < 0 Then
Return New ValidationResult(False, "負の値は入力できません")
Else
Return New ValidationResult(True, Nothing)
End If
End Function
End Class
Inherits ValidationRule
Public Overrides Function Validate(ByVal value As Object, ByVal cultureInfo As System.Globalization.CultureInfo) As System.Windows.Controls.ValidationResult
Dim result As Integer
If Not Integer.TryParse(CType(value, String), result) Then
Return New ValidationResult(False, "整数値を入力してください。")
ElseIf result < 0 Then
Return New ValidationResult(False, "負の値は入力できません")
Else
Return New ValidationResult(True, Nothing)
End If
End Function
End Class
今回のようにTextBoxのTextプロパティでバインドしている場合であればValidateメソッドのValueにString型の値が入ってきますが、たとえばSliderのValueでバインドしている場合にはDouble型が入ってくるようになります。作ったValidationRuleはさまざまなところで使われる可能性がありますので、他の型が入ってくることも考慮した実装にしておいたほうが良いかもしれません。
入力データ検証シリーズも6回を迎えましたが、まだ続きます。次回は個々のプロパティ単位ではなくソースオブジェクト全体の検証を行う方法についてご紹介する予定です。