validation - Xamarin 表单中的验证的好解决方案?
问题描述
我正在寻找一个优雅的表单验证解决方案。
我在 Enterprise Apps 中找到了这个 Validation,但它不适用于类。
当前解决方案:
public class ItemModel
{
[Required]
public string UserName { get; set; }
[Required]
public string Password { get; set; }
}
public class NewItemViewModel : BaseViewModel
{
private ValidatableObject<string> _userName = new ValidatableObject<string>();
public ValidatableObject<string> UserName
{
get => _userName;
set => SetProperty(ref _userName, value);
}
private ValidatableObject<string> _password = new ValidatableObject<string>();
public ValidatableObject<string> Password
{
get => _password;
set => SetProperty(ref _password, value);
}
public NewItemViewModel()
{
AddValidations();
}
public void Save(){
var itemModel = new ItemModel { UserName = UserName.Value, Password = Password.Value };
//TODO do something
}
private void AddValidations()
{
_userName.ValidationRules.Add(new IsNotNullOrEmptyRule<string> { ValidationMessage = "A username is required." });
_password.ValidationRules.Add(new IsNotNullOrEmptyRule<string> { ValidationMessage = "A password is required." });
}
}
我想仅在模型上指定验证,并能够通过 View、ViewModel 中的字段进行检查。
解决方案
我这样做了,但它仍然是视图的模型。
优点是验证链接到模型而不是视图。
有必要将模型转换为背面。
public class ItemModel : ObservableObject
{
private ValidatableObject<string> _userName = new ValidatableObject<string>();
public ValidatableObject<string> UserName
{
get => _userName;
set => SetProperty(ref _userName, value);
}
private ValidatableObject<string> _password = new ValidatableObject<string>();
public ValidatableObject<string> Password
{
get => _password;
set => SetProperty(ref _password, value);
}
public ItemModel(string userName, string password)
{
UserName.Value = userName;
Password.Value = password;
AddValidations();
}
public bool Validate()
{
var isValidUserName = ValidateUserName();
var isValidPassword = ValidatePassword();
return isValidUserName && isValidPassword;
}
public bool ValidateUserName()
{
return _userName.Validate();
}
public bool ValidatePassword()
{
return _password.Validate();
}
private void AddValidations()
{
_userName.ValidationRules.Add(new IsNotNullOrEmptyRule<string> { ValidationMessage = "A username is required." });
_password.ValidationRules.Add(new IsNotNullOrEmptyRule<string> { ValidationMessage = "A password is required." });
}
}
public class NewItemViewModel : BaseViewModel
{
public ItemModel ItemModel { get; set; }
public NewItemViewModel()
{
Title = "New ItemModel";
ItemModel = new ItemModel("Username", "P@ssword");
}
public ICommand SaveCommand => new AsyncCommand(Save);
private async Task Save()
{
if (ItemModel.Validate())
{
var itemModel = new ItemModel(ItemModel.UserName.Value, ItemModel.Password.Value);
await Application.Current.MainPage.DisplayAlert("Item", $"{itemModel.UserName} {itemModel.Password}", "Ok");
}
}
public ICommand ValidateUserNameCommand => new Command(() => ItemModel.ValidateUserName());
public ICommand ValidatePasswordCommand => new Command(() => ItemModel.ValidatePassword());
}
推荐阅读
- python - 引发 exc.NoSuchModuleError(sqlalchemy.exc.NoSuchModuleError:无法加载插件:sqlalchemy.dialects:mysql.pymysql
- python-3.x - 使用 sympy 将方程转换为另一种形式
- powershell - PowerShell get-childitem 拒绝排除目录
- javascript - 提交到新 URL 后如何访问表单数据
- android - 删除事件后,警报/提醒是否会自动删除?
- java - 如何解决 BiConsumer java 电报机器人的问题
- node.js - NgFor 仅支持绑定到诸如 Arrays 之类的 Iterables。找不到不同的支持对象
- javascript - 如何使用第 2 行的 readline 模块开始读取文件?
- ruby-on-rails - 工头在“工头启动”后关闭彪马
- html - 我的下拉列表中的标签在图像上不可点击