環境
.NET 5
WPF
Prism 8.0.0
前提・実現したいこと
MVVMの設計に従ってアカウント登録の実装をしているのですが、
アカウント登録時のValidation処理をどう行うか困っています…
ModelでValidationを実行する場合には、
どうエラーメッセージを通知するのがよいのでしょうか。
シナリオ
ユーザは、画面上にある
- ユーザ名
- パスワード
- パスワードの入力確認
上記三つの項目を入力し、「登録」ボタンをクリックします。
その際、下記条件に当てはまらない場合に、PrismのErrorContainerを介して、画面上にエラーメッセージが表示されます。
- ユーザ名
1文字以上入力されている
登録されていないアカウント名である
- パスワードの入力確認
パスワードと一致する
発生している問題・エラーメッセージ
ユーザ名が1文字以上であるかはRequiredAttribute、
パスワードの入力確認はCompareAttributeで判定できますが、
既存ユーザアカウント名との重複判定とエラー通知をModelで行う場合は、
Actionやdelegateを使用するものなのでしょうか。
例えば、ViewModelのコンストラクタ内で、エラー時に呼び出されるModelの関数にErrorContainerへの処理を追加し、
エラー判定時に下記処理をModel内で呼び出すようなイメージです。
C#
1delegate void OnValidationError(string errorMessage)
新たに、特定のユーザ名を使用できないようにし、エラーメッセージ「使用できないユーザ名です」と表示させたり、
エラーの内容によって、通知先のプロパティが異なる場合(今回でいうと、Passwordにmanager側で判定するような処理が追加された場合)は、
別のdelegate(もしくはActionなど)を定義するのでしょうか。
コード
C#
1 2public class ValidatableBase : Prism.Mvvm.BindableBase, INotifyDataErrorInfo 3{/* 処理は省略、ErrorContainerはerrorsとしてprivate定義 */} 4 5public class VM : ValidatableBase 6{ 7 [Required] 8 public string UserName{ get => _account.UserName; set => _account.UserName = value; } 9 10 public string Password{ get => _account.Password; set => _account.Password = value; } 11 12 [Compare(nameof(Password))] 13 public string Confirm{ get; set; } 14 15 // Accountは 16 public ICommand RegisterCommand { get; } 17 18 public VM(AccountManager manager) 19 { 20 RegisterCommand = new DelegateCommand(()=> manager.Register(_account)); 21 manager.OnValidationError += message => errors.SetErrors(nameof(UserName), new[]{ message }); 22 } 23 24 private Account _account; 25} 26 27public class AccountManager 28{ 29 // このようなdelegateが、ケース毎に用意される…? 30 public delegate void OnValidationError(string errorMessage); 31 32 public List<Account> Accounts{ get; private set; } 33 34 public void Register(Account account) 35 { 36 if (Accounts.Contain(account)) 37 { 38 OnValidationError("既に存在しているユーザ名です"); 39 return; 40 } 41 if(/* 例えば、既存パスワードとの重複を禁止する場合 */) 42 { 43 /* 新しいdelegateを呼び出す? */ 44 return; 45 } 46 } 47} 48 49public Account 50{ 51 public string UserName{ get => _userName; set => SetProperty(ref _userName, value); } 52 public string Password{ get => _password; set => SetProperty(ref _password, value); } 53 54 /* 比較時にUserNmaeで確認する処理 */ 55 56 private string _userName; 57 private string _password; 58} 59
回答2件
あなたの回答
tips
プレビュー