In order to be able to provide meaningful messages to the user, it is best to make the properties of your ViewModel, which must be bound to the TextBox of the type string and implement IDataErrorInfo on your ViewModel.
In my projects, I use it like this. I created an IValidateable interface (please forgive the name ...) that implements IDataErrorInfo. My ViewModel implements this interface:
public interface IValidateable : IDataErrorInfo { ObservableCollection<Tuple<string, ValidationError>> InvalidProperties { get; } bool IsValid { get; } }
All my text fields use the following style:
<Style TargetType="{x:Type TextBox}"> <Style.Triggers> <Trigger Property="Validation.HasError" Value="true"> <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}" /> </Trigger> </Style.Triggers> <Setter Property="Validation.ErrorTemplate"> <Setter.Value> <ControlTemplate> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="90*" /> <ColumnDefinition Width="20" /> </Grid.ColumnDefinitions> <Border BorderBrush="Red" BorderThickness="1" CornerRadius="2.75" Grid.Column="0"> <AdornedElementPlaceholder Grid.Column="0" /> </Border> <TextBlock Foreground="Red" Grid.Column="1" Margin="0" FontSize="12" VerticalAlignment="Center" HorizontalAlignment="Left"> * </TextBlock> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
This shows the tooltip if the value entered does not match my rules.
In addition, I created a small validation mechanism that allows you to assign rules to the properties of the view model and a base class that automatically checks the value of the property when setting a new value.
The IValidateable interface IValidateable are used to display a meaningful error message to the user when trying to save an invalid object.
source share