Подтвердить что ты не робот

Странная проблема, при которой Button не получает повторного включения, если щелкнуть мышью

Мое приложение написано с использованием шаблона MVVM в WPF, и все мои кнопки используют привязки команд для выполнения кода в моей модели. Все команды имеют код в CanExecute для определения связанного состояния кнопки Включено. Логика работает отлично, но во всех случаях графический интерфейс остается в отключенном состоянии, если я не щелкнул в другом месте в графическом интерфейсе.

Например, у меня есть кнопка Disard Candy. Когда я нажимаю эту кнопку, он запускает процесс в потоке threadpool, который устанавливает свойство bool под названием "Выполнение" true. Поскольку метод CanExecute для команды Discard Candy выглядит примерно так:

public bool CanExecute(object parameter)
{
  return !Running;
}

кнопка будет отключена после запуска процесса. Проблема заключается в том, что при выполнении процесса Running получает значение false, но графический интерфейс не обновляется, т.е. Отказ от конфеты не активируется.

Однако, если я нажимаю в любом месте графического интерфейса, например, в окне или в строке заголовка, внезапно активируется кнопка "Сбросить конфету". Итак, логика работает, но что-то происходит, я просто не понимаю. Может ли кто-нибудь объяснить мне это поведение?

EDIT - пока это похоже на CommandManager.InvalidateRequerySposed не помогло людям. Я собираюсь сделать это, но на данный момент я немного опасаюсь этого. Я выполнил рекомендуемые ссылки и при этом решил больше узнать о инструментах MVVM light. Это звучит очень хорошо - кто-нибудь здесь использовал его и смог подтвердить, что он не показывает проблему, которую я видел до сих пор? Хотя я планирую попробовать инструментарий MVVM light tool в следующем крупном rev. моего приложения, я не хочу переделывать все команды, которые у меня есть в настоящее время, поэтому я, скорее всего, начну с CommandManager.InvalidateRequerySposed, поэтому мы все можем получить другую точку данных здесь относительно ее полезности.

EDIT # 2 - очень интересно, инструмент MVVM light tool на самом деле полагается на CommandManager.InvalidateRequerySposed для поддержки возможности пользовательского интерфейса отключать/повторно активировать команды. Автор говорит:

"Строго говоря, в WPF, и если ваша команда привязана к элементу управления, который просматривается CommandManager, вам не нужно поднимать событие CanExecuteChanged самостоятельно. Вы можете позволить CommandManager обрабатывать ситуацию. Тем не менее, внешние события может также изменить состояние пользовательского интерфейса. Предположим, что пользовательский интерфейс должен быть включен с 9 утра до 5 вечера, а затем отключен на ночь. Пользователь не запускает пользовательский интерфейс, поэтому код должен запросить (вежливо), что CommandManager запрашивает состояние команд. Это делается путем вызова метода InvalidateRequerySposed в CommandManager. И, как вы догадались, метод RaiseCanExecuteChanged класса RelayCommand делает именно это."

4b9b3361

Ответ 1

WPF не обновляет элементы управления, привязанные к команде, если у него нет причин. Нажатие на GUI заставляет WPF обновляться, поэтому обновление работает.

Вы можете вручную вызвать обновление любых связанных с командой элементов управления, вызвав CommandManager.InvalidateRequerySuggested.

Ответ 2

Моя проблема, казалось, была связана с привязкой команд - я использовал RelayCommand как часто делаю, но рендеринг кнопки просто не был корректным, пока я не нажал на окно.

Удаление кода CanExecute из CommandBinding и использование свойства IsEnabled вместо этого решило мою проблему без головной боли - это заняло целую вечность, пока я не попробовал это среди многих других вещей, которые могли быть проблемой.

Ответ 3

Иногда установка фокуса на родительский элемент управления вызывает запуск CommandManager CanExecute. Попробуйте следующее после установки "Выполнение" на "false":

...
Running = false;
parentControl.Focusable = true;
parentControl.Focus();