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

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

Сообщение Anonymous »

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

Код: Выделить всё

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, просто в случай...
RelayCommand.cs

Код: Выделить всё

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#»