Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data Validation in MVVM light

What is the best way to do data validation. Is it a good practice to do validation in view models or should the validation be done in models? and also, what is the best way to implement numeric(decimal) text-box in WPF with MVVM. I am using MVVM Light toolkit.

like image 535
katie77 Avatar asked Sep 27 '11 14:09

katie77


1 Answers

To be able to provide meaningful messages to the user, it is best to make the properties of your ViewModel that should be bound to a TextBox of type string and implement IDataErrorInfo on your ViewModel.

In my projects, I am using it like this. I created an interface IValidateable (please forgive the name...) which implements IDataErrorInfo. My ViewModel implements this interface:

public interface IValidateable : IDataErrorInfo
{
    ObservableCollection<Tuple<string, ValidationError>> InvalidProperties
    { get; }
    bool IsValid { get; }
}

All my text boxes 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 will show a tool tip if the value entered doesn't conform to my rules.

Furthermore, I created a small validation engine which allows to assign rules to the properties of the view model and a base class that automatically validates the property value when a new value is set.
The interface members of IValidateable are used to display a meaningful error message to the user when he tries to save an invalid object.

like image 86
Daniel Hilgarth Avatar answered Sep 30 '22 13:09

Daniel Hilgarth