验证WPF应用程序中的必填字段

本文关键字:字段 WPF 应用程序 验证 | 更新日期: 2023-09-27 18:11:50

我正在开发一个c#/WPF应用程序,其中我有多个视图(说a,B,C等)和相应的视图模型。开发人员将在未来的应用程序中添加许多新的视图。每个视图都有各种控件,如文本框、组合框、日期时间选择器等。

我正在尝试为必需的字段提出一种验证方法,以便开发人员需要添加最少的代码来验证新添加的视图上的控件。

我当前的方法:

我所有的视图模型都继承自一个名为"ViewModelBase"的基类。我在这个类中添加了一个名为IsRequiredFieldValueBlank()的新方法:

public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable
        public bool IsRequiredFieldValueBlank(object inputObject)
        {
            bool isRequiredFieldValueBlank = true;
            try
            {
                var arrProperties = inputObject.GetType().GetProperties();
                foreach (var prop in arrProperties)
                {
                    if (!prop.CanWrite)
                        continue;
                    if(prop.PropertyType.Name.ToUpper() == "STRING")
                    {                        
                        if (string.IsNullOrEmpty(prop.GetValue(inputObject).ToString()))
                        {
                            isRequiredFieldValueBlank = true;
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
              //TBD:Handle exception here
            }
            return isRequiredFieldValueBlank;
        }
}

在视图"A"的xaml代码中,我有以下代码:

<TextBox HorizontalAlignment="Left" Height="23" VerticalAlignment="Top" Width="180" TabIndex="1" Text="{Binding ProductDescription,NotifyOnSourceUpdated=True,  UpdateSourceTrigger=PropertyChanged}" Style="{DynamicResource RequiredFieldStyle}" Grid.Row="1"  Grid.Column="3"  Margin="1,10,0,0" />

在我的mainwindoresources。xaml

<Style TargetType="TextBox" x:Key="RequiredFieldStyle">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=ViewModelBase.IsRequiredFieldValueBlank}" Value="false">
                <Setter Property="Background" Value="BurlyWood" />
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=ViewModelBase.IsRequiredFieldValueBlank}" Value="true">
                <Setter Property="Background" Value="LightGreen" />
                <Setter Property="Foreground" Value="DarkGreen" />
            </DataTrigger>            
        </Style.Triggers>
    </Style>

App.xaml:

<Application x:Class="MyTool.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml"
             Startup="Application_Startup">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Views/MainWindowResources.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

我的问题:1.这是正确的方法吗?如果是,那么我理解代码不会工作,因为xaml没有将inpoObject传递给ViewModelBase类中的IsRequiredFieldValueBlank()方法。有人能告诉我如何实现这个目标吗?

2。请问还有其他方法可以处理这个问题吗?

谢谢你的帮助。

验证WPF应用程序中的必填字段

如果您将Validator静态类与IDataErrorInfoINotifyPropertyChanged接口结合起来进行验证,那么从长远来看,您的工作就会轻松得多。下面是对PRISM的BindableBase类进行扩展的一个非常基本的实现:

public abstract class ViewModelBase : IDataErrorInfo, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public string Error => string.Join(Environment.NewLine, GetValidationErrors());
    public bool IsValid => !GetValidationErrors().Any();
    public string this[string columnName] =>
        GetValidationErrors().FirstOrDefault(result => result.MemberNames.Contains(columnName))?.ErrorMessage;
    protected IEnumerable<ValidationResult> GetValidationErrors()
    {
        var context = new ValidationContext(this);
        var results = new List<ValidationResult>();
        Validator.TryValidateObject(this, context, results, true);
        return results;
    }
    protected virtual void OnPropertChanged([CallerMemberName]string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName]string propertyName = null)
    {
        if (Equals(storage, value))
        {
            return false;
        }
        storage = value;
        OnPropertChanged(propertyName);
        return true;
    }
}

你也不需要RequiredFieldStyle文件。验证可以这样完成:

public class ViewModelExample : ViewModelBase
{
    private string _myString;
    // do validation with annotations and IValidateableObject
    [Required]
    [StringLength(50)]
    public string MyString
    {
        get { return _myString; }
        set { SetProperty(ref _myString, value); }
    }
}

在保存前检查IsValid属性,看看对象是否有效