【问题标题】:Passing Validation into a DelegateCommand将验证传递给 DelegateCommand
【发布时间】:2017-07-11 20:47:22
【问题描述】:

我有一个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 =&gt; Register());

如果CanRegister 返回 false,则提示或拒绝该过程?

【问题讨论】:

  • 尝试阅读here的答案,可能会有帮助
  • “我将如何在此处的调用中实现 CanRegister()”——这是什么意思? 实现 CanRegister() 是将代码放入方法体中,即将您现在拥有的return true; 替换为真实代码。要使用方法“在此处调用”意味着简单地调用例如方法中的方法。一个 lambda,即_registerCommand = new DelegateCommand(param =&gt; Register(), param =&gt; CanRegister());想做什么?你实际上需要什么帮助?代码现在在做什么,确切地你想让它做什么,你尝试了什么,具体你需要什么帮助?

标签: c# wpf mvvm


【解决方案1】:

通常的方法是禁用命令按钮,直到满足所有验证条件。在您的情况下,您有两个验证规则(用户名不存在,密码匹配规则)我会执行以下操作:

  1. 在用户键入时检查用户名是否存在。显然您不希望在每次击键后触发数据库调用,因此请在绑定中使用延迟选项。在 ViewModel 中设置一个属性以反映结果,例如是用户名唯一。设置此属性时,请在您的 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

【讨论】:

    猜你喜欢
    • 2017-08-16
    • 1970-01-01
    • 2021-07-23
    • 1970-01-01
    • 2020-07-12
    • 2016-04-27
    • 2016-02-29
    • 1970-01-01
    • 2015-02-27
    相关资源
    最近更新 更多