Когда canExecute не вызывается в первый раз , это проблема связывания.
Если это не «автоматически» вызывается секунда, [n] -й раз, это нормальное поведение.
Представьте себе, как пользовательский интерфейс должен знать , что он должен запрашивать ваш предикат? Если у вас есть параметр команды , он будет вызывать ваш предикат каждый раз, когда изменяется параметр. Обычно некоторые события пользовательского интерфейса также требуют его (focus, updatelayout и т. Д.), Но не всегда (это хорошо, было бы бессмысленно переоценивать каждую привязку команды все время). Таким образом, вы не можете положиться на это. Вы создаете бизнес-логику, поэтому вы знаете , когда требуется обновление, а не пользовательский интерфейс. Пользовательский интерфейс «не может видеть внутри вашего предиката делегата» и смотреть, что происходит. Вы должны уведомить пользовательский интерфейс об этом, так же, как вы уведомляете, когда свойство изменилось .
ICommand имеет событие, поэтому вы должны реализовать его, это CanExecuteChanged .
Вы должны реализовать публичный метод для его запуска (или он уже реализован, если вы используете фреймворк, такой как MVVMLight или Prism).
Простая реализация.
public void RaiseCanExecuteChanged()
{
var handler = CanExecuteChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
Таким образом, вы можете вызывать его по вашей команде всякий раз, когда ваше состояние canExecute изменяется в вашей бизнес-логике, и оно собирается уведомлять всех подписчиков, что в данном случае является вашей кнопкой .