Прежде всего: не странно, что кнопка не активируется после выполнения метода Foo
, так как последняя строка отключает кнопку.
Если вы хотите «увидеть»Изменение состояния кнопки включено, вам нужно обработать сообщения окна перед сном.Thread.Sleep
вызывает поток пользовательского интерфейса в спящем режиме, поэтому обновления пользовательского интерфейса не будут.Что вам нужно сделать, это заставить приложение обрабатывать все ожидающие сообщения окна.
public static void DoEvents()
{
if (Application.Current != null)
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { }));
}
public void Foo()
{
button1.IsEnabled = false
DoEvents();
Thread.Sleep(3000);
button1.IsEnabled = true;
DoEvents();
Thread.Sleep(3000);
button1.IsEnabled = false;
}
РЕДАКТИРОВАТЬ
Дальнейшее объяснение:
Когда первый Thread.Sleep
вызвана, кнопка отключена (IsEnabled
is false
).Затем, подождав 3 секунды, вы устанавливаете кнопку в положение «включено», а после этого снова отключаете ее.Кнопка фактически находится в этом состоянии, но визуальной обратной связи нет (например, если вы посмотрите на форму, кнопка не будет мигать).
Это потому, что вы блокируетеUI поток по телефону Thread.Sleep
.Это препятствует тому, чтобы окно получало оконные сообщения, которые сообщают окну, когда перерисовывать себя или одного из его дочерних элементов (кнопка не «знает», что она должна быть серой).
Таким образом, вам нужно дать окновозможность получать сообщения и обновлять своих детей.В приложениях Windows Forms это было сделано с помощью Application.DoEvents
, который обрабатывал все ожидающие сообщения окна.
В WPF нет такой вещи, как Application.DoEvents
, но код, который я разместил, эмулирует это, вызывая Thread
, которая ничего не делает, но этого небольшого промежутка времени между изменением включенного состояния кнопки и блокировкой потока пользовательского интерфейса достаточно для перекрашивания элемента управления кнопки.