Validation Error Style in Wpf, Similar to Silverlight

Validation Error Style in WPF, similar to Silverlight

I studied the Silverlight version of the Validation Error Template and created a WPF version of it which looks like this

Sample Image
Added an animated GIF at the bottom of the post but after I finished it I noticed that it might be annoying because of the moving mouse in it. Let me know if I should remove it.. :)

I used a MultiBinding with a BooleanOrConverter to show the "tooltip-error" when the TextBox has Keyboard focus or the Mouse is over the upper right corner. For the fade-in animation I used a DoubleAnimation for the Opacity and a ThicknessAnimation with a BackEase/EaseOut EasingFunction for the Margin

Useable like this

<TextBox Validation.ErrorTemplate="{StaticResource errorTemplateSilverlightStyle}" />

errorTemplateSilverlightStyle

<ControlTemplate x:Key="errorTemplateSilverlightStyle">
<StackPanel Orientation="Horizontal">
<Border BorderThickness="1" BorderBrush="#FFdc000c" CornerRadius="0.7"
VerticalAlignment="Top">
<Grid>
<Polygon x:Name="toolTipCorner"
Grid.ZIndex="2"
Margin="-1"
Points="6,6 6,0 0,0"
Fill="#FFdc000c"
HorizontalAlignment="Right"
VerticalAlignment="Top"
IsHitTestVisible="True"/>
<Polyline Grid.ZIndex="3"
Points="7,7 0,0" Margin="-1" HorizontalAlignment="Right"
StrokeThickness="1.5"
StrokeEndLineCap="Round"
StrokeStartLineCap="Round"
Stroke="White"
VerticalAlignment="Top"
IsHitTestVisible="True"/>
<AdornedElementPlaceholder x:Name="adorner"/>
</Grid>
</Border>
<Border x:Name="errorBorder" Background="#FFdc000c" Margin="1,0,0,0"
Opacity="0" CornerRadius="1.5"
IsHitTestVisible="False"
MinHeight="24" MaxWidth="267">
<Border.Effect>
<DropShadowEffect ShadowDepth="2.25"
Color="Black"
Opacity="0.4"
Direction="315"
BlurRadius="4"/>
</Border.Effect>
<TextBlock Text="{Binding ElementName=adorner,
Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"
Foreground="White" Margin="8,3,8,3" TextWrapping="Wrap"/>
</Border>
</StackPanel>
<ControlTemplate.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource BooleanOrConverter}">
<Binding ElementName="adorner" Path="AdornedElement.IsKeyboardFocused" />
<Binding ElementName="toolTipCorner" Path="IsMouseOver"/>
</MultiBinding>
</DataTrigger.Binding>
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="fadeInStoryboard">
<Storyboard>
<DoubleAnimation Duration="00:00:00.15"
Storyboard.TargetName="errorBorder"
Storyboard.TargetProperty="Opacity"
To="1"/>
<ThicknessAnimation Duration="00:00:00.15"
Storyboard.TargetName="errorBorder"
Storyboard.TargetProperty="Margin"
FillBehavior="HoldEnd"
From="1,0,0,0"
To="5,0,0,0">
<ThicknessAnimation.EasingFunction>
<BackEase EasingMode="EaseOut" Amplitude="2"/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="fadeInStoryboard"/>
<BeginStoryboard x:Name="fadeOutStoryBoard">
<Storyboard>
<DoubleAnimation Duration="00:00:00"
Storyboard.TargetName="errorBorder"
Storyboard.TargetProperty="Opacity"
To="0"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>

BooleanOrConverter

public class BooleanOrConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
foreach (object value in values)
{
if ((bool)value == true)
{
return true;
}
}
return false;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
}

Sample Image

What effective alternatives are there to UI validation error visualization than stock I*DataErrorInfo?

In the XamGrid case, I implemented INotifyDataErrorInfo as in "the pattern", but instead of listening for notifications, I just checked the backing error collection in a conditional cell formatter.

wpf error template - red box still visible on collapse of an expander

Rather than doing any binding, you could place an AdornerDecorator around the elements inside of your expander. You see, the validation error template is placed on the adorner layer that way it shows up on top of everything else. That's ultimately what your problem is. Even though your text box is not visible because the expander is closed, the error template is still on the adorner layer.

I believe you can fix this with the following xaml:

<Expander Header="Blah Blah Blah">
<AdornerDecorator>
<TextBox Name="TextBox"
Validation.ErrorTemplate="{DynamicResource TextBoxErrorTemplate}"
Text="{Binding Path=Blah,
UpdateSourceTrigger=PropertyChanged,
ValidatesOnDataErrors=True}" />
</AdornerDecorator>
</Expander>

This creates an adorner layer specifically for within the expander. When the expander is closed the AdornerDecorator also gets hidden and so should everything on it.

Change Error Title in Silverlight

The Validation Summary has a Header property. You could simply set it in XAML or Codebehind and completely overwrite it.

If you need a bit more control, then override the HeaderTemplate. The default is too long to past here, but the important part is:

<DataTemplate x:Key="myNewAndImprovedErrorHeaderThanksToMiguel">
<!--There's a border, stackpanel and other funky, but irrelevant tags-->
<TextBlock Padding="4,1,0,0" Text="{Binding}" Foreground="#FFFFFFFF" FontWeight="Bold"/>
</DataTemplate/>

Now, you could simply use a converter for the Text to slightly modify it. The Binding's value will by default contain the text "# Error".

Silverlight DataGrid validation show validation error for all objects|properties

I haven't succeeded with a TextBlock control, so I used a disabled TextBox
You can change the template of the TextBox, I mean to remove border and to set its background really transparent.

multi row validatione

<sdk:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Items}" IsReadOnly="False" SelectionMode="Single">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Header="Title" Binding="{Binding Title}"/>
<sdk:DataGridTemplateColumn Header="Link" Width="100">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Link, Mode=TwoWay}" Margin="2"
IsEnabled="False" BorderThickness="0" Background="Transparent"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
<sdk:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox Text="{Binding Link, Mode=TwoWay}" Margin="2"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellEditingTemplate>
</sdk:DataGridTemplateColumn>
</sdk:DataGrid.Columns>
</sdk:DataGrid>

about silverlight textbox validation

here you can find how you can style the validation tooltip:
Silverlight: How to style the validation tooltip?

This can solve your problem.

In addition you could disable the validation on your binding. How do you validate your input? If you have set the NotifyOnValidationError and the ValidatesOnExceptions to true, remove it (it is false by default). Or if you use validation via INotifyDataErrorInfo you have to set the ValidatesOnNotifyDataErrors to false (this is true by default).

Hope this helps.

BR,

TJ

wpf error template - red box still visible on collapse of an expander

Rather than doing any binding, you could place an AdornerDecorator around the elements inside of your expander. You see, the validation error template is placed on the adorner layer that way it shows up on top of everything else. That's ultimately what your problem is. Even though your text box is not visible because the expander is closed, the error template is still on the adorner layer.

I believe you can fix this with the following xaml:

<Expander Header="Blah Blah Blah">
<AdornerDecorator>
<TextBox Name="TextBox"
Validation.ErrorTemplate="{DynamicResource TextBoxErrorTemplate}"
Text="{Binding Path=Blah,
UpdateSourceTrigger=PropertyChanged,
ValidatesOnDataErrors=True}" />
</AdornerDecorator>
</Expander>

This creates an adorner layer specifically for within the expander. When the expander is closed the AdornerDecorator also gets hidden and so should everything on it.



Related Topics



Leave a reply



Submit