従来 自己流で行っていた直接UI要素をゴリゴリいじくる方法は、UI要素とビジネスロジックを疎結合にしたい
との流れから WPFの流儀に反しイケテナイ方法のようです。ようやく 自分なりに理解できる 検証方法にたどり着いたので POSTします。実現した処理は、エラーになったTextBoxの背景色をピンクにエラー内容をToolTipに表示することです。
作成したWindow
テキストボックスとボタンのみの画面
・ボタンはフォーカス移動のためダミーで配置
・テキストボックス:正の整数のみOK
・エラー時の処理 背景色をピンクに、ToolTipにエラー内容を表示
整数以外を入力すると
マイナスを入力すると
当然ですが、正しい値を入力すると 背景色は白のままです。
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




0 件のコメント:
コメントを投稿