Странное поведение canExecute в Mvvmlight RelayCommand
Я учусь Mvvmlight, и довольно смущен canExecute
RelayCommand.
В основном у меня есть Button
и PasswordBox
в view
и Command
в viewModel
Что я хочу, это отключить кнопку, если PasswordBox пуст. Моё решение - передать PasswordBox как CommandParemeter кнопке, затем получить PasswordBox в методе canExecute и указать, является ли он пустым или пустым. Сначала я объявляю команду:
public ICommand CommandClear { get; private set; }
Затем создайте его в Class Constructor
:
CommandConfirm = new RelayCommand<object>((p) => ConfirmExecute(p), (p) => ConfirmCanExecute(p));
Наконец, реализовать canExecute
метод, как показано ниже:
private bool ConfirmCanExecute(object parameter)
{
bool isExecuable = false;
var passwordBox = parameter as PasswordBox;
if (!string.IsNullOrEmpty(passwordBox.Password))
isExecuable = true;
return isExecuable;
}
Вышеуказанный метод canExecute не работает, как необработанное исключение. System.Reflection.TargetInvocationException
будет брошен в PresentationFramework.dll
,
Поэтому я пытаюсь обернуть код выше с try...catch
На этот раз это работает как волшебство:
try
{
var passwordBox = parameter as PasswordBox;
if (!string.IsNullOrEmpty(passwordBox.Password))
isExecuable = true;
return isExecuable;
}
catch
{
return isExecuable;
}
Я довольно смущен таким поведением canExecute
,есть идеи?
1 ответ
Вы объявляете p в стеке в этой строке и все еще существует, когда вызывается обработчик?
CommandConfirm = new RelayCommand<object>((p) => ConfirmExecute(p), (p) => ConfirmCanExecute(p));
Потому что неправильная привязка команды, безусловно, приведет к тому, что это вернет null, создавая ошибку, которую вы видите
var passwordBox = parameter as PasswordBox;
Во-вторых, почему ваша ViewModel напрямую манипулирует этим видом? Просто 2-сторонняя привязка поля Password к вашей ViewModel и обработчик CanExecute вашей ViewModel становится однострочным, нет?
return !String.IsNullOrEmpty(this.Password);