はじめに
この記事ではValidationRuleクラスを使って入力データの妥当性検証を行う方法を確認します。
プロジェクトのファイル構成は下図のとおりです。

開発環境は以下のとおりです。
オペレーティングシステム | Windows10 x64 |
Visual Studio | Microsoft Visual Studio Community 2019 Version 16.11.2 |
.NET Framewrok | 4.7.2 |
動作の仕様
動作の仕様は、TextBoxコントロールに100未満の正の整数が入力された場合は妥当性検証は成功とし、それ以外の数値等が入力された場合は失敗とします。
成功時のウィンドウは以下のとおりです。

失敗時のウィンドウは以下のとおりとします。

- 赤い枠線を表示する
- 背景を薄いピンク色にする
- 右側にエラーメッセージを表示する
- ツールチップにエラーメッセージを表示する
ValidationRuleクラスを使用する
バインディングソースとして使用するPositiveNumberプロパティを定義したValidatingNumber.csは以下のとおりです。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WpfValidatingData2
{
class ValidatingNumber
{
public int PositiveNumber { get; set; }
}
}
以下のMinNumberRule.csでは、ValidationRule抽象クラスを継承しValidate抽象メソッドをオーバーライドすることによってカスタムルールを定義します。このような方法で実装するのはWPFの決まりです。
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace WpfValidatingData2
{
class MinNumberRule : ValidationRule
{
private const string MESSAGE = "100未満の正の整数を入力してください";
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
try
{
string val = (string)value;
int inputNumber = string.IsNullOrWhiteSpace(val) ? -1 : int.Parse(val);
if (inputNumber < 1 || inputNumber > 99)
{
// 失敗時
return new ValidationResult(false, MESSAGE);
}
// 成功時
return ValidationResult.ValidResult;
}
catch (Exception)
{
// 数値以外の文字やintの最大値より大きい数値が入力された場合など
return new ValidationResult(false, MESSAGE);
}
}
}
}
XAMLファイルは以下のとおりです。
<Window x:Class="WpfValidatingData2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfValidatingData2"
mc:Ignorable="d"
Title="MainWindow" Height="250" Width="600">
<Window.Resources>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Background" Value="LightPink"/>
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
<ControlTemplate x:Key="_errorTemplate">
<StackPanel Orientation="Horizontal">
<Border BorderBrush="Red" BorderThickness="2" Margin="0,0,6,0">
<AdornedElementPlaceholder x:Name="_el"/>
</Border>
<TextBlock Text="{Binding AdornedElement.(Validation.Errors)[0].ErrorContent, ElementName=_el}"
Foreground="Red" HorizontalAlignment="Right"
VerticalAlignment="Center" Margin="0,0,10,0"/>
</StackPanel>
</ControlTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="240"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="1" Text="正の整数 : " FontSize="20" TextAlignment="Right" Margin="10"/>
<TextBox Grid.Row="1" Grid.Column="1" FontSize="20" Margin="2"
Validation.ErrorTemplate="{StaticResource _errorTemplate}">
<TextBox.Text>
<Binding Path="PositiveNumber" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:MinNumberRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</Grid>
</Window>
プロパティ要素構文を使ってTextBox.TextにBindingインスタンスを定義します。ここではマークアップ拡張構文は使えません。Binding.ValidationRulesにはカスタムルールを定義したMinNumberRuleインスタンスを設定します。
リソースで定義しているAdornedElementPlaceholderを含むカスタムテンプレート_errorTemplateはTextBoxの右側にエラーメッセージを表示するためのものです。詳細については以下の記事をご確認ください。
コードビハインドは以下のとおりです。DataContextを設定しています。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfValidatingData2
{
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ValidatingNumber { PositiveNumber = 5 };
}
}
}
以上の実装で仕様どおりの動作をすることがわかります。
その他詳細については以下の記事などをご確認ください。

今回はValidationRuleクラスを使って入力データの妥当性検証を行う方法について確認しました。
以上です。
コメント