2017-07-11 24 views
0

我有一個DelegateCommand,看起來像這樣:傳遞驗證到DelegateCommand

public class DelegateCommand : ICommand 
{ 
    private readonly Predicate<object> _canExecute; 
    private readonly Action<object> _execute; 

    public event EventHandler CanExecuteChanged; 

    public DelegateCommand(Action<object> execute) 
     : this(execute, null) 
    { 
    } 

    public DelegateCommand(Action<object> execute, Predicate<object> canExecute) 
    { 
     _execute = execute; 
     _canExecute = canExecute; 
    } 

    public bool CanExecute(object parameter) 
    { 
     return _canExecute == null || _canExecute(parameter); 
    } 

    public void Execute(object parameter) 
    { 
     _execute(parameter); 
    } 

    public void RaiseCanExecuteChanged() 
    { 
     CanExecuteChanged?.Invoke(this, EventArgs.Empty); 
    } 
} 

我有一個過程,允許用戶註冊到一個數據庫中。不過,我需要在添加一些驗證,例如,沒有用戶名已經存在,不會密碼匹配規則等。這裏是寄存器命令:

#region RegisterCommand 

private DelegateCommand _registerCommand; 
public ICommand RegisterCommand 
{ 
    get 
    { 
     _registerCommand = new DelegateCommand(param => Register()); 
     return _registerCommand; 
    } 
} 

private bool CanRegister() 
{ 
    return true; 
} 

private void Register() 
{ 
    var newUser = new User 
    { 
     FirstName = _firstname, 
     LastName = _lastname, 
     Username = _username, 
     Password = "", // TODO: Hashing and storing of passwords 
    }; 
    using (var context = new WorkstreamContext()) 
    { 
     var users = context.Set<User>(); 
     users.Add(newUser); 
     context.SaveChanges(); 
    } 
} 

#endregion 

正如你所看到的,我已經叫CanRegister()了一種方法,我想用來過濾註冊過程。我的問題是,我將如何實現在這裏呼籲CanRegister()

_registerCommand = new DelegateCommand(param => Register());

提示或拒絕的過程中,如果CanRegister返回false?

+0

嘗試從[這裏]閱讀答案(https://stackoverflow.com/questions/23110880/wpf-command-binding -with-input-validation-how-to-enable-the-save-button-only),可能會有幫助 – bogdanbrizhaty

+0

_「我將如何在調用中實現CanRegister()」_ - 這是什麼意思?要_implement_''CanRegister()'就是把代碼放在方法體中,即用真正的代碼替換'return true;'現在你已經有了。在這裏調用_方法_「意味着簡單地調用例如lambda,即'_registerCommand = new DelegateCommand(param => Register(),param => CanRegister());'。你想要做什麼?你實際需要什麼幫助?代碼現在在做什麼,你希望它做什麼_precisely_,你試過了什麼,以及你需要什麼特別的幫助? –

回答

0

通常的做法是在所有驗證條件都滿足之前禁用命令按鈕。在你的情況,你有兩個驗證規則(用戶名不存在,密碼匹配規則)我會做到以下幾點:。

  1. 檢查用戶名存在用戶鍵入它顯然你不每次擊鍵後都不希望數據庫調用觸發,因此請在綁定中使用「延遲」選項。在ViewModel中設置一個屬性以反映結果,例如IsUserNameUnique。設置此屬性時,請在DelegateCommand上調用RaiseCanExecuteChanged方法。

  2. 使用IsStrongPassword重複此過程作爲密碼。

  3. 將您的DelegateCommand掛鉤到其構造函數中的CanRegister方法中。這將禁用該命令,直到CanRegister返回true。

  4. 將您的CanRegister命令更改爲僅當IsStrongPassword和IsUserNameUnique都爲true時才返回true。

延遲綁定:

<TextBox Text="{Binding UserName, Delay=500, UpdateSourceTrigger=PropertyChanged}" /> 

視圖模型

#region RegisterCommand 

private DelegateCommand _registerCommand; 
public ICommand RegisterCommand 
{ 
    get 
    { 
     _registerCommand = new DelegateCommand(param => Register(),() => CanRegister()); 
     return _registerCommand; 
    } 
} 

private bool CanRegister() 
{ 
    return _isUserNameUnique && _isStrongPassword; 
} 

public string UserName 
{ 
get {return _userName;} 
set 
{ 
    _userName = value; 
    OnUserNameChanged(); 
} 
} 

public string Password 
{ 
get {return _password;} 
set {_password = value; OnPasswordChanged(); 
} 

private void OnUserNameChanged() 
{ 
    _isUserNameUnique = VerifyUserNameIsUnique(_userName); 
    _registerCommand.RaiseCanExecuteChanged(); 
} 

private void OnPasswordChanged() 
{ 
    _isStrongPassword = VerifyIsStrongPassword(); 
    _registerCommand.RaiseCanExecuteChanged(); 
} 

private void Register() 
{ 
    var newUser = new User 
    { 
     FirstName = _firstname, 
     LastName = _lastname, 
     Username = _username, 
     Password = "", // TODO: Hashing and storing of passwords 
    }; 
    using (var context = new WorkstreamContext()) 
    { 
     var users = context.Set<User>(); 
     users.Add(newUser); 
     context.SaveChanges(); 
    } 
} 

#endregion