开发者

WPF MVVM Validation Problem using MVVM-Helpers validation attributes

开发者 https://www.devze.com 2023-01-26 21:50 出处:网络
I\'m working on a new C#4.0 / Prism 4 applicaiton using the JulMar Mvvm-Helpers to help with my MVVM implementation.I have a problem with my validation logic.In the past, I\'ve been using Prism 2.2 /

I'm working on a new C#4.0 / Prism 4 applicaiton using the JulMar Mvvm-Helpers to help with my MVVM implementation. I have a problem with my validation logic. In the past, I've been using Prism 2.2 / Enterprise Library Validation Block successfully. But for this project, I'm trying something new.

My XAML Code is below.

<UserControl x:Class="DoSomeThing.Views.D开发者_如何学编程oSomeThingView"
         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>

The code to bind the view to the viewmodel is

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

All the editing logic works as do the validation attributes on the view model. My problem is with the bool CanSaveCommand(object param) function to prevent saving if any validation errors are present.

I do not see how to detect that there are any validation errors present. Suggestions?


To solve my problem, I ended up calling the viewmodel validation routine explicitly and checking the result.

My viewmodel inherited from ValidatingViewModel base class. That allows access to the static ValidationManager class as follows -

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

With the first parameter null, it tests all properties on the viewmodel that have validation attributes. Then if the returned error message string's length > 0, you can detect that there is a validation error present.

0

精彩评论

暂无评论...
验证码 换一张
取 消