viewmodel + Catel 上的验证

Posted

技术标签:

【中文标题】viewmodel + Catel 上的验证【英文标题】:Validation on viewmodel + Catel 【发布时间】:2015-07-20 19:19:56 【问题描述】:

我正在尝试在 Catel 中的 viewModel 上实现验证。

我阅读了文档,它看起来很简单,但不知何故,我可能在这种特殊情况下遗漏了一些东西。我有一个用户控件,其中嵌套了两个用户控件。一个是我将用作自定义命令栏的用户控件,另一个是模型的详细视图。

<catel:UserControl x:Class="SICUAP.Views.CatProducto_CategoriasView"
               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
               xmlns:catel="http://catel.codeplex.com"
               xmlns:Views="clr-namespace:SICUAP.Views">

<!-- Resources -->
<UserControl.Resources>
</UserControl.Resources>

<!-- Content -->
<catel:StackGrid>
    <catel:StackGrid.RowDefinitions>
        <RowDefinition></RowDefinition>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </catel:StackGrid.RowDefinitions>
    <Views:cmdGlobalesBDView></Views:cmdGlobalesBDView>
    <Label Content="Catalogo de Categorias de Producto" Style="StaticResource estiloTituloControl">
    </Label>
    <Views:dataProducto_CategoriasView />

</catel:StackGrid>

命令栏只有一个绑定到全局命令的按钮。

<Button Width="50" Height="50" VerticalAlignment="Center" HorizontalAlignment="Center" ToolTip="Salvar" Command="catel:CommandManagerBinding Salvar"
                    Style="StaticResource MetroCircleButtonStyle">
        <Rectangle Width="20" Height="20" Fill="Binding Path=Foreground, RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type Button" >
            <Rectangle.OpacityMask>
                <VisualBrush Stretch="Fill" Visual="StaticResource appbar_save" />
            </Rectangle.OpacityMask>
        </Rectangle>
    </Button>

这是详细视图

<catel:UserControl x:Class="SICUAP.Views.dataProducto_CategoriasView"
               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
               xmlns:catel="http://catel.codeplex.com">
<UserControl.Resources>
</UserControl.Resources>
<catel:StackGrid>
    <catel:StackGrid.RowDefinitions>
        <RowDefinition Height="Auto" />
    </catel:StackGrid.RowDefinitions>
    <GroupBox Header="Datos de la Categoria del Producto">
        <catel:StackGrid>
            <catel:StackGrid.RowDefinitions>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
            </catel:StackGrid.RowDefinitions>
            <catel:StackGrid.ColumnDefinitions>
                <ColumnDefinition Width="300"></ColumnDefinition>
                <ColumnDefinition Width="100"></ColumnDefinition>
                <ColumnDefinition Width="200"></ColumnDefinition>
            </catel:StackGrid.ColumnDefinitions>
            <Label Content="Nombre:"></Label>
            <Label Content="Activo:"></Label>
            <catel:EmptyCell></catel:EmptyCell>
            <TextBox Margin="5" Text="Binding Nombre, ValidatesOnDataErrors=True, NotifyOnValidationError=True"></TextBox>
            <CheckBox Margin="5" IsChecked="Binding Activo"></CheckBox>
            <catel:EmptyCell></catel:EmptyCell>
            <Label Content="Descripcion:"></Label>
            <catel:EmptyRow></catel:EmptyRow>
            <TextBox Margin="5" TextWrapping="Wrap" AcceptsReturn="True" Grid.ColumnSpan="3" Height="200" Text="Binding Descr,ValidatesOnDataErrors=True, NotifyOnValidationError=True"></TextBox>
        </catel:StackGrid>
    </GroupBox>
</catel:StackGrid>

我创建命令并将其绑定到详细视图模型的构造函数上的验证摘要。

public dataProducto_CategoriasViewModel(ICommandManager commandManager, IMessageService messageService )
    
        Catel.Argument.IsNotNull(() => commandManager);
        Catel.Argument.IsNotNull(() => messageService);
        _commandManager = commandManager;
        _messageService = messageService;            
        Salvar = CommandHelper.CreateCommand(OnSalvarExecute,()=>CategoriaProductoValidationSummary);
        _commandManager.RegisterCommand(Comandos.Catalogos.Salvar, Salvar, this);
    

这是我的验证摘要的属性和 ValidateFields 的覆盖。

[ValidationToViewModel(Tag = "ValidacionCategoriaProducto")]
    public IValidationSummary CategoriaProductoValidationSummary  get; set; 

    protected override void ValidateFields(List<IFieldValidationResult> validationResults)
    
        if (string.IsNullOrEmpty(Nombre))
            validationResults.Add(FieldValidationResult.CreateErrorWithTag(NombrePropiedad, "Nombre es requerido","ValidacionCategoriaProducto"));
        if (string.IsNullOrEmpty(Descr))
            validationResults.Add(FieldValidationResult.CreateErrorWithTag(DescrPropiedad, "Descripcion es requerido", "ValidacionCategoriaProducto"));           
    

ValidateFields 永远不会触发。并且该按钮始终处于启用状态。我是否缺少服务注册或其他内容?

【问题讨论】:

您可以尝试点击确定/保存吗?验证可能会延迟到第一次保存调用。 【参考方案1】:

已经发现我的错误了。使用 Orchestra 模板创建项目时,它会在 App.xaml.cs 的开头添加此行

Catel.Windows.Controls.UserControl.DefaultCreateWarningAndErrorValidatorForViewModelValue = false;
Catel.Windows.Controls.UserControl.DefaultSkipSearchingForInfoBarMessageControlValue = true;
Catel.Data.ModelBase.SuspendValidationForAllModels = true;

它们会禁用验证功能,因此删除它们应该绰绰有余。

【讨论】:

以上是关于viewmodel + Catel 上的验证的主要内容,如果未能解决你的问题,请参考以下文章

Catel 中的嵌套验证

Catel 中的 ViewModel 集合

[Catel]如何将带有构造函数参数的 ViewModel 传递给 TabService 扩展方法?

Catel:具有一个View的多个ViewModel。可能吗?

Catel ViewModelToModel 没有链接

Catel DependencyInjection问题