RelayCommand RaiseCanExecuteChanged () завершается ошибкой - PullRequest
3 голосов
/ 04 августа 2011

Я использую пару кнопок, связанных с RelayCommands, инициализированными с делегатами CanExecute.

RelayCommand DeleteCommand;
bool CanDelete()
{
    return BoolProp1 && BoolProp2;
}

...

DeleteCommand = new RelayCommand(Delete, CanDelete);

BoolProp1 и BoolProp2 - это обычные свойства с правильными установщиками, повышающими PropertyChanged, но, как мы все знаемэтого недостаточно для того, чтобы SL переоценивал CanExecute для команд.Вот почему я также вызываю Delete.RaiseCanExecuteChanged() в обоих установках.

Все это работает нормально (кнопки отключены и включены правильно) до некоторой точки, где все останавливается.В этот момент вызов Delete.RaiseCanExecuteChanged() больше не вызывает мои контрольные точки в CanDelete(), и кнопки навсегда остаются такими же, как и были.

Я провожу 2 часа, пытаясь выделить точную причину без какого-либо эффекта.Я подозреваю, что несколько вызовов RaiseCanExecuteChanged() во время одной итерации привязки как-то нарушают механизм.

Есть какие-нибудь подсказки?Я уже рассматриваю возможность использования дополнительного поля IsExecutable, обновленного через INotifyPropertyChanged ...

ОБНОВЛЕНИЕ

RelayCommand на самом деле GalaSoft.MvvmLight.Command.RelayCommand с MVVM Light Toolkit .ILSpy показывает довольно тривиальную реализацию ICommand:

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

public void RaiseCanExecuteChanged()
{
    EventHandler canExecuteChanged = this.CanExecuteChanged;
    if (canExecuteChanged != null)
    {
         canExecuteChanged.Invoke(this, EventArgs.Empty);
    }
}

с _canExecute, являющимся Func<bool>, установленным один раз на значение, переданное конструктору.

Я все еще работаю над минимальным воспроизведениемвыпуск.

ОБНОВЛЕНИЕ

Смотрите мой ответ.

1 Ответ

7 голосов
/ 04 августа 2011

PEBKAC.Мой фреймворк в некоторых случаях запускал код

DeleteCommand = new RelayCommand(Delete, CanDelete);

более одного раза, перезаписывая команды, которые фактически были связаны для просмотра новыми экземплярами.

Если у кого-то есть такая проблема - убедитесь, что вывызов RelayCommand.RaiseCanExecuteChanged() в том же экземпляре, к которому привязано представление.

...