2010-11-26 8 views
0

Je travaille sur une nouvelle application C# 4.0/Prism 4 en utilisant le JulMar Mvvm-Helpers pour faciliter mon implémentation MVVM. J'ai un problème avec ma logique de validation. Dans le passé, j'ai utilisé Prism 2.2/Enterprise Library Validation Block avec succès. Mais pour ce projet, j'essaie quelque chose de nouveau.Problème de validation MVVM WPF à l'aide des attributs de validation MVVM-Helpers

Mon code XAML est ci-dessous.

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

Le code pour lier la vue sur la viewmodel est

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

Toute la logique d'édition fonctionne comme les attributs de validation du modèle de vue. Mon problème est avec la fonction bool CanSaveCommand(object param) pour empêcher l'enregistrement si des erreurs de validation sont présentes.

Je ne vois pas comment détecter des erreurs de validation. Suggestions?

Répondre

0

Pour résoudre mon problème, j'ai fini par appeler explicitement la routine de validation viewmodel et vérifier le résultat.

Mon viewmodel hérité de ValidatingViewModel classe de base. Cela permet d'accéder à la classe ValidationManager statique comme suit: -

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

Avec le premier paramètre null, il teste toutes les propriétés sur la viewmodel qui ont des attributs de validation. Ensuite, si le message d'erreur renvoyé est de longueur> 0, vous pouvez détecter qu'une erreur de validation est présente.