【问题标题】:WPF Validating a sub-class property with IDataErrorInfoWPF 使用 IDataErrorInfo 验证子类属性
【发布时间】:2021-09-22 11:13:00
【问题描述】:

给出下一个例子:

型号

public class ProjecteModel : ObservableObject, IProjecteModel
{
    private string _patientID

    public string IdPacient
    {
        get => _idPacient;
        set
        {
            _idPacient = value;
            OnPropertyChanged(nameof(IdPacient));
        }
    }

    /* More fields here... */
}

其中 ObservableObject 是实现 INotifyPropertyChanged 接口的基类。

视图模型

public class ProjecteViewModel : BaseViewModel, IDataErrorInfo
{
    private IProjecteModel _projecte = new ProjecteModel();
    private string _codiClient;

    public IProjecteModel Projecte
    {
        get => _projecte;
        set
        {
            _projecte = value;
            OnPropertyChanged(nameof(Projecte));
        }
    }

    public string CodiClient
    {
        get => _codiClient;
        set 
        { 
            _codiClient = value;
            OnPropertyChanged(nameof(CodiClient));
        }
    }

    public string this[string columnName]
    {
        get
        {
            string msg = String.Empty;
            switch (columnName)
            {
                case "CodiClient":
                    if (CodiClient.Length <= 0)
                    {
                        msg = "ID Client is required.";
                    }
                    break;

                case "IdPacient":
                //case "Projecte.IdPacient":
                    if (Projecte.IdPacient.Length <= 0)
                    {
                        msg = "Id Pacient is required.";
                    }
                    break;
            };

            return msg;
        }
    }
}

查看

    <!-- Id Pacient -->
    <StackPanel Orientation="Vertical" 
                Width="{Binding ElementName=capComandes, Path=ItemsWidth}">
        <TextBlock Text="ID Pacient:" 
                    Style="{StaticResource FieldNameTextBlock}"/>
        <TextBox x:Name="IdPacient"
                    Width="150" 
                    HorizontalAlignment="Left"
                    Margin="0, 0, 0, 15"
                    Foreground="{StaticResource ForegroundFieldValuesBrush}"
                    Text="{Binding Projecte.IdPacient, 
                                   Mode=TwoWay, 
                                   UpdateSourceTrigger=PropertyChanged, 
                                   ValidatesOnDataErrors=True}"/>
    </StackPanel>

    <!-- CodiClient -->
    <StackPanel Orientation="Vertical" 
                Width="{Binding ElementName=capComandes, Path=ItemsWidth}">
        <TextBlock Text="ID Client:" 
                   Style="{StaticResource FieldNameTextBlock}"/>
        <TextBox x:Name="IdClient"
                 Width="150" 
                 HorizontalAlignment="Left"
                 Foreground="{StaticResource ForegroundFieldValuesBrush}"
                 Text="{Binding CodiClient, 
                                Mode=TwoWay, 
                                UpdateSourceTrigger=PropertyChanged, 
                                ValidatesOnDataErrors=True}">
                        </TextBox>
    </StackPanel>

验证适用于 CodiClient,但不适用于 IdPacient。

验证方法:从不为 IdPacient 调用 public string this[string columnName]

如何验证子类属性?

【问题讨论】:

  • 请注意,自 .NET 4.5 起实现属性验证的推荐方法是实现 INotifyDataErrorInfo 接口。
  • @BionicCode 是的,我已经阅读过,感谢您的建议..

标签: wpf validation


【解决方案1】:

IDataErrorInfo 需要在包含您要绑定的属性的任何类中实现。

看看我的blog post,我的基本可绑定对象类实现了IDataErrorInfo,并包含一个虚拟的ValidatePropety() 方法,该方法从public string this[string columnName] {} 属性调用。然后根据需要在每个后代类中覆盖它,以对特定属性执行实际验证。

public class perObservableObject: ObservableObject, IDataErrorInfo
{
    private HashSet<string> InvalidProperties { get; } = new HashSet<string>();

    public virtual bool IsValid => !InvalidProperties.Any();

    public bool HasError(string propertyName) => InvalidProperties.Contains(propertyName);

    protected virtual string ValidateProperty(string propertyName) => string.Empty;

    public string this[string columnName]
    {
        get
        {
            if (nameof(IsValid).Equals(columnName))
                return string.Empty;

            var result = ValidateProperty(columnName);

            var errorStateChanged = string.IsNullOrWhiteSpace(result)
                ? InvalidProperties.Remove(columnName)
                : InvalidProperties.Add(columnName);

            if (errorStateChanged)
                RaisePropertyChanged(nameof(IsValid));

            return result;
        }
    }

    // IDataErrorInfo - redundant in WPF
    public string Error => string.Empty;
}

[ObservableObject 来自 MvvmLight]

【讨论】:

  • 嗨,INotifyDataErrorInfo 也必须应用于所有类吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-31
  • 2014-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多