MVVM中的数据验证

时间:2011-09-27 14:09:48

标签: wpf mvvm mvvm-light

进行数据验证的最佳方法是什么。在视图模型中进行验证还是在模型中进行验证是一种好的做法?而且,使用MVVM在WPF中实现数字(十进制)文本框的最佳方法是什么。我正在使用MVVM Light工具包。

3 个答案:

答案 0 :(得分:6)

为了能够向用户提供有意义的消息,最好将ViewModel的属性绑定到类型为string的TextBox,并在ViewModel上实现IDataErrorInfo

在我的项目中,我正在使用它。我创建了一个实现IDataErrorInfo的接口IValidateable(请原谅名称......)。我的ViewModel实现了这个接口:

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

我的所有文本框都使用以下样式:

<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>

如果输入的值不符合我的规则,这将显示工具提示。

此外,我创建了一个小型验证引擎,它允许为视图模型的属性分配规则,以及在设置新值时自动验证属性值的基类。
IValidateable的接口成员用于在用户尝试保存无效对象时向用户显示有意义的错误消息。

答案 1 :(得分:1)

在类上实现IDataError Info并实现两个属性Error和这个[string columnName]你可以用你想要的绑定错误实现第二个属性

public class MainViewModel:ViewModelBase,IDataErrorInfo  
{

public string Error
   {
   }
 public string this[string columnName]

 {
  get
      {
         string msg=nulll;
         switch(columnName)
            {
              case "MyProperty": //that will be your binding property
               //choose your validation logic
               if(MyProperty==0||MyProperty==null)
                 msg="My Property is required";
                break;
             }
         return msg;
        }
}

还在字段

上设置ValidateOnError = true

答案 2 :(得分:0)

如果您使用IDataErrorInfo进行Viewmodel验证 - 请勿忘记以下内容:

如果你的viewmodel有其他属性,那么typeof string并且视图中的输入无法转换为属性类型 - 那么你的输入永远不会到达viewmodel,所以验证 - 以及视图前面的用户只是在想:“wtf为什么我没有看到任何验证错误!”