验证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。请问还有其他方法可以处理这个问题吗?
谢谢你的帮助。
如果您将Validator
静态类与IDataErrorInfo
和INotifyPropertyChanged
接口结合起来进行验证,那么从长远来看,您的工作就会轻松得多。下面是对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
属性,看看对象是否有效