SourceChord

C#とXAML好きなプログラマの備忘録。最近はWPF系の話題が中心です。

WPFでの入力値検証・その4 ~ErrorTemplateで検証結果の表示をカスタマイズ~

WPFの入力検証ネタの続きです。
Validationのエラー表示をカスタマイズしてみます。


Varidation.ErrorTemplate添付プロパティに、表示したい内容のControlTemplateを設定することで、エラー時の表示をカスタマイズすることができます。
ControlTemplateの内容は、AdornedElementPlaceholderが検証対象のコントロールの場所と揃うように配置されます。

サンプルコード

前回のサンプルを少し拡張して、テキストボックスが空の時と、10文字より長く入力されたときにエラーを出すようにしました。

f:id:minami_SC:20140610000631p:plain f:id:minami_SC:20140610000634p:plain
MainWindow.xaml
<Window x:Class="WpfBaseTemplate1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfBaseTemplate1"
        Title="MainWindow"
        Width="525"
        Height="350">
    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>
    <Window.Resources>
        <ControlTemplate x:Key="ValidationTemplate">
            <StackPanel>
                <TextBlock Foreground="Red" Text="{Binding AdornedElement.(Validation.Errors)[0].ErrorContent, ElementName=adornedelem}" />
                <AdornedElementPlaceholder x:Name="adornedelem" />
            </StackPanel>
        </ControlTemplate>
    </Window.Resources>
    <Grid>
        <TextBox Width="120"
                 Height="23"
                 Margin="50"
                 HorizontalAlignment="Left"
                 VerticalAlignment="Top"
                 Text="{Binding InputString,
                                UpdateSourceTrigger=PropertyChanged}"
                 Validation.ErrorTemplate="{StaticResource ValidationTemplate}">
        </TextBox>
    </Grid>
</Window>
MainWindowViewModel.cs

VMは以下のように、Required属性を付加して、InputStringプロパティが空白の時にエラーを通知するようにしました。

        private string inputString;
        [Required(ErrorMessage = "何か入力してください")]
        [StringLength(10, ErrorMessage = "10文字以内で入力してください")]
        public string InputString
        {
            get { return inputString; }
            set
            {
                this.SetProperty(ref this.inputString, value);
                ValidateProperty("InputString", value);
            }
        }

        public MainWindowViewModel()
        {
            this.InputString = string.Empty;
        }