WPF 入力データの検証

WPFの勉強を進めると DataBindingの活用に 大きな特徴があり、入力データの検証でも活用するのが一般的なやり方のようです。
従来 自己流で行っていた直接UI要素をゴリゴリいじくる方法は、UI要素とビジネスロジックを疎結合にしたい との流れから WPFの流儀に反しイケテナイ方法のようです。ようやく 自分なりに理解できる 検証方法にたどり着いたので POSTします。実現した処理は、エラーになったTextBoxの背景色をピンクにエラー内容をToolTipに表示することです。


作成したWindow
no0
テキストボックスとボタンのみの画面
・ボタンはフォーカス移動のためダミーで配置
・テキストボックス:正の整数のみOK
・エラー時の処理 背景色をピンクに、ToolTipにエラー内容を表示

整数以外を入力すると
no2

マイナスを入力すると
no3

当然ですが、正しい値を入力すると 背景色は白のままです。
no1


MainWindow.xaml

<Window x:Class="WpfApplication5CS.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:WpfApplication5CS" mc:Ignorable="d" Title="MainWindow" Height="250" Width="400">
    <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}"/>
                    <Setter Property="Background" Value="#ffeeff" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="100"/>
        </Grid.ColumnDefinitions>
        <TextBox x:Name="TextBox" VerticalAlignment="Top" Grid.Column="1" Grid.Row="1" FontSize="18" Text="{Binding ID, ValidatesOnDataErrors=True}" />
        <Button x:Name="button" Content="ボタン(ダミー)" Grid.Column="1" Margin="0" Grid.Row="3" VerticalAlignment="Top" FontSize="18"/>
    </Grid>
</Window>

Window.Resourcesで Target:TextBoxにエラーがあれば、ToolTipにエラー内容を表示し、背景色をピンクにすることを指定しています。
TextBoxの定義では、DataContexのプロパティ:IDにバウンドしデータエラーの検出を行うことを指定しています。

MainWindow.xaml.cs

using System.Windows;
namespace WpfApplication5CS
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            // InitializeComponent() 呼び出しの後で初期化を追加します。
            this.DataContext = new DataSource();
        }
    }
}

DataContextにDataSourceクラスを用いることを追加しただけで、VisualStudioのテンプレートをそのまま使っています。

DataSource.cs DataContextに指定したクラスです。

using System;
using System.ComponentModel;

namespace WpfApplication5CS
{
    class DataSource: IDataErrorInfo
    {
        public String ID
        {
            get; set;
        }

        // 今回は使わないが、IDataErrorInfo インターフェースでは実装しなければならない
        public string Error { get { return null; } }

        // これも実装必須のプロパティで、各プロパティに対応するエラーメッセージを返す
        public string this[string propertyName]
        {
            get
            {
                string result = null;

                switch (propertyName)
                {
                    case "ID":
                        if (this.ID == null) return null;

                        int ii;
                        try
                        {
                            ii = int.Parse(this.ID);
                        }
                        catch (Exception e)
                        {
                            result = "IDは整数値を入力してください。";
                            break;
                        }
                        if (ii < 0)
                            result = "IDは0以上の整数値を入力してください。";
                        break;
                }
                return result;
            }
        }
    }
}

IDをintで定義して setアクセサーで直接代入してもほぼ同様の結果になりますが、初期画面を表示した際 エラー状態になることを回避するためこのような処理を行っています。

DataBindingなんて、きっとAccessが登場した時からある DataBindみたいなものだろう とタカをくくっていた のぼったにとっては、目が点になることばかり。 ようやく 流儀に少しはかなうデータ検証方法が実装できました。これでどんなプログラムを作ろうか?


参考にしたURL

スポンサーリンク
Rectangle大広告
Rectangle大広告

シェアする

  • このエントリーをはてなブックマークに追加

フォローする