使用MVVM-Helpers验证属性的WPF MVVM验证问题

时间:2010-11-26 16:46:24

标签: c# wpf validation mvvm

我正在使用JulMar Mvvm-Helpers开发一个新的C#4.0 / Prism 4应用程序来帮助我的MVVM实现。我的验证逻辑有问题。过去,我一直在成功使用Prism 2.2 / Enterprise Library Validation Block。但对于这个项目,我正在尝试新的东西。

我的XAML代码如下。

<UserControl x:Class="DoSomeThing.Views.DoSomeThingView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:Converters="clr-namespace:JulMar.Windows.Converters;assembly=JulMar.Wpf.Helpers" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" >
<UserControl.Resources>
    <Converters:ValidationErrorConverter x:Key="errorConverter"/>
    <Style TargetType="{x:Type TextBox}">
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="ToolTip" 
                  Value="{Binding RelativeSource={RelativeSource Self}, 
                    Path=(Validation.Errors), Converter={StaticResource errorConverter}}"/>
                <Setter Property="Background" Value="Red" />
                <Setter Property="Foreground" Value="White" />
            </Trigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>
<Grid Name="EditGrid" Margin="3">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="10" />
        <ColumnDefinition Width="100" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Label Grid.Column="1" Grid.Row="0" Content="Name" Height="21" VerticalAlignment="Top" />
    <Label Grid.Column="1" Grid.Row="1" Content="Address" />
    <Label Grid.Column="1" Grid.Row="2" Content="Zip" />
    <Label Grid.Column="1" Grid.Row="3" Content="Number Of Doors" />
    <Label Grid.Column="1" Grid.Row="4" Content="Double Number" />


    <TextBox Grid.Column="2" Grid.Row="0" Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=LostFocus, NotifyOnValidationError=True, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" 
             HorizontalAlignment="Left" VerticalAlignment="Top" Width="200" />
    <TextBox Grid.Column="2" Grid.Row="1" Text="{Binding Path=Address, Mode=TwoWay, UpdateSourceTrigger=LostFocus, NotifyOnValidationError=True, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" 
             HorizontalAlignment="Left" VerticalAlignment="Top" Width="200"/>
    <TextBox Grid.Column="2" Grid.Row="2" Text="{Binding Path=Zip, Mode=TwoWay, UpdateSourceTrigger=LostFocus, NotifyOnValidationError=True, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" HorizontalAlignment="Left" 
             VerticalAlignment="Top" Width="200"/>
    <TextBox Grid.Column="2" Grid.Row="3" Text="{Binding Path=NumberOfDoors, Mode=TwoWay, UpdateSourceTrigger=LostFocus, NotifyOnValidationError=True, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" 
             HorizontalAlignment="Left" Height="21" Width="200"/>
    <TextBox Grid.Column="2" Grid.Row="4" Text="{Binding Path=DoubleNumber, Mode=TwoWay, 
        UpdateSourceTrigger=LostFocus, NotifyOnValidationError=True, ValidatesOnDataErrors=True, 
        ValidatesOnExceptions=True}" 
             HorizontalAlignment="Left" VerticalAlignment="Top" Width="200"/>
    <Button Content="Save" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="4" Height="23" 
            HorizontalAlignment="Left" Margin="26,41,0,0" Name="button1" VerticalAlignment="Top"
            Width="75" Command="{Binding SaveCommand}"/>
</Grid>

将视图绑定到viewmodel的代码是

            IRegion region = this._regionManager.Regions["MainRegion"];
        var v = new DoSomeThingView();
        var model = new SampleDataModel
            {
                Name = "hello",
                NumberOfDoors = 5,
                Zip = "12345",
                DoubleNumber = 321.12,
                Address = "no where's ville"
            };

        var vm = new SampleDataViewModel { DataModel = model };

        v.EditGrid.DataContext = vm;
        region.Add(v);

所有编辑逻辑的工作方式与视图模型上的验证属性一样。我的问题是使用bool CanSaveCommand(object param)函数来防止在存在任何验证错误时进行保存。

我不知道如何检测是否存在任何验证错误。建议?

1 个答案:

答案 0 :(得分:0)

为了解决我的问题,我最终明确地调用了viewmodel验证例程并检查了结果。

我的viewmodel继承自ValidatingViewModel基类。这允许访问静态ValidationManager类,如下所示 -

private bool CanSaveExecute(object param)
{
    string v = ValidationManager.Validate(null, this);
    bool b = v.Length == 0;
    return b;
}

使用第一个参数null,它会测试viewmodel上具有验证属性的所有属性。然后,如果返回的错误消息字符串的长度> 0,您可以检测到存在验证错误。