エラーメッセージがViewを切り替えると消える事への対処方法
課題
一つ前の記事で、第5回のエラー処理のサンプルを作成した時に、バリエーションによるエラーメッセージを表示した状態で、一覧から別の項目を選択すると、Viewが切り替わり、右側に新しい画面が表示される。
その後、元の項目を表示すると再びViewが切り替わり、バリエーションエラーが発生している画面が表示される。
この時、切り替え前には表示されていたエラーメッセージが消えてしまう。入力フォームに赤い枠があるため、バリエーションエラーは発生しているのがわかる。
AdornedElement の関連の設定だと思い、色々と調べた結果、Viewが切り替わってもエラーメッセージが消えない方法を編み出した。
エラー処理で検索してヒットするのは、WPF コントロール(TextBox)等のValidation.ErrorTemplate プロパティに、リソースとして定義しておいたControlTemplateを設定する方法だが、
この方法だと上記の通りViewが切り替わるとエラーメッセージが消えてしまう。
参考: Nine Works INotifyDataErrorInfoを使用したデータ検証
そこで、Validation.ErrorTemplate への設定方法を変えると上手くいく。
対処方法
<UserControl.Resources> <Style x:Key="ErrorStyle" TargetType="TextBox"> <Setter Property="Margin" Value="4" /> <Style.Triggers> <Trigger Property="IsVisible" Value="True"> <Setter Property="Validation.ErrorTemplate"> <Setter.Value> <ControlTemplate> <DockPanel> <ItemsControl DockPanel.Dock="Bottom" Margin="5,0" ItemsSource="{Binding ElementName=adornedElement, Path=AdornedElement.(Validation.Errors)}"> <ItemsControl.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding ErrorContent}" Foreground="Red"/> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> <Border BorderBrush="Red" BorderThickness="1" Width="{Binding ElementName=adornedElement, Path=ActualWidth}" Height="{Binding ElementName=adornedElement, Path=ActualHeight}"> <AdornedElementPlaceholder Name="adornedElement"/> </Border> </DockPanel> </ControlTemplate> </Setter.Value> </Setter> </Trigger> </Style.Triggers> </Style> </UserControl.Resources>
コントロールの属性として指定するのではなく、Styleに設定し、条件を満たしたときに反映されるようにする。
具体的には、Style.Triggerを使用して指定する。トリガーの条件は「IsVisible」プロパティが 「true」になっている事。
条件を満たした場合、Validation.ErrorTemplate にControlTemplateを設定するようにすると、Viewを切り替えてもエラーメッセージが表示される。
使用する場合は、Styleプロパティに設定する。
<TextBox Text="{Binding Author, UpdateSourceTrigger=PropertyChanged}" Width="200" Margin="5,0,5,20" HorizontalAlignment="Left" Style="{StaticResource ErrorStyle}"></TextBox>
ちなみに、エラーが発生しているかどうかはコントロールが持っており、エラーがなくなるとValidation.ErrorTemplate が空になってメッセージは消える。