ICommand: кнопка отключения-включения во время длительного запуска процесса с помощью Task.Run()C#

Место общения программистов C#
Ответить
Anonymous
 ICommand: кнопка отключения-включения во время длительного запуска процесса с помощью Task.Run()

Сообщение Anonymous »

Приложение WPF с использованием MVVM — я впервые пытаюсь использовать CanExecute для ICommand, поэтому будьте терпеливы.
Кнопка привязана к команде в модели представления. При нажатии кнопки выполняется длительный процесс (я вызываю его с помощью await Task.Run(), чтобы пользовательский интерфейс не блокировался).
Затем я обновляю ObservableCollection в модели представления, чтобы отобразить результаты в пользовательском интерфейсе, но я не включаю эту часть здесь для простоты.
Теперь я хочу отключить кнопку при ее нажатии и снова включить ее после длительного процесса. заканчивается. Я объявил частное поле и свойство в модели представления IsBusy, а в методе, связанном с CanExecute команды, я возвращаю true или false в зависимости от значения этого свойства.
Это половина работы: при нажатии кнопки она отключается. Затем, когда процесс завершается, пользовательский интерфейс показывает результаты в порядке, НО кнопка не активируется повторно... только когда я после этого нажимаю где-нибудь в пользовательском интерфейсе, кнопка снова активируется.
Это в моем XAML:


Вот модель представления:
public class MyViewModel : BaseViewModel {
public ICommand DoProcessCommand { get; private set; }

private bool _isBusy;

public bool IsBusy {
get { return _isBusy; }
set { _isBusy = value; OnPropertyChanged(nameof(IsBusy)); }
}

// ctor
public MyViewModel() {
DoProcessCommand = new RelayCommand(DoProcessCommandMethod, CanDoProcessCommandMethod);
IsBusy = false;
}

// Command Execute
private bool CanDoProcessCommandMethod(object parameter) {
return !IsBusy;
}

// Command CanExecute
private async void DoProcessCommandMethod(object parameter) {
IsBusy = true;
var results = await Task.Run(() => MyService.someLongProcess());
// so something with the results...
IsBusy = false;
// more code here...
}
}

Любая помощь?
Примечание: метод, выполняющий длинный процесс, не является асинхронным, я просто вызываю его внутри await Task.Run(), чтобы он не блокировал поток пользовательского интерфейса... Я просто упоминаю об этом на случай, если это на что-то повлияет...
ОБНОВЛЕНИЕ
Я забыл добавить свою реализацию RelayCommand, просто случай:
public class RelayCommand : ICommand {
readonly Action _execute = null;
readonly Predicate _canExecute = null;

public RelayCommand(Action execute)
: this(execute, null) {
}

public RelayCommand(Action execute, Predicate canExecute) {
if (execute == null)
throw new ArgumentNullException("execute");

_execute = execute;
_canExecute = canExecute;
}

public bool CanExecute(object parameter) {
return _canExecute == null ? true : _canExecute((T)parameter);
}

public event EventHandler CanExecuteChanged {
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}

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


Подробнее здесь: https://stackoverflow.com/questions/798 ... h-task-run
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»