2013-08-01 2 views
0

В настоящее время я запускаю довольно длинную операцию с моего основного вида. В то время как эта операция продолжается, не должно быть никаких нажатий кнопки на основном экране. Кроме того, прогресс следует сообщать в другом окне. Я могу обновить все свойства CanXXX Guard, но это будет тонны кода.Caliburn.Micro блокировка основного вида

Я хотел бы использовать метод ShowDialog для Caliburn.Micro, но эти методы ждут, пока окно не вернется с возвращаемым значением. Итак, как я могу показать модальное окно с Caliburn.Micro, которое не ждет возврата какого-либо диалога?

+0

Почему возникает проблема? Закройте его, когда операция будет выполнена. Диалоговое окно - это самый простой способ заблокировать главное окно. –

+0

Проблема заключается в том, что вызывающий метод должен работать после открытия диалога. Я мог перенести эту часть в Диалог, но это пахнет. –

+0

Если это длинный метод, он должен быть в потоке (bgw) в любом случае. Храните его в виртуальной машине. –

ответ

2

Я делал это в прошлом ...

В вашей основной/зрения оболочки -

<ContentControl IsEnabled="{Binding UILocked, Converter={StaticResource BooleanInverter}}"> 
    <SomeOtherControls..... blah blah /> 
</ContentControl> 

В ViewModel главная/оболочка -

public bool UILocked { get { // getter } set { // prop changed code/setter etc... } } 

После установки UILocked для истины весь пользовательский интерфейс должен быть отключен. ContentControl отключит все дочерние элементы и IsEnabled привязок для своих детей, будут игнорироваться

Вы можете убедиться, что основной вид подписывается на агрегатор события тоже:

public class MainViewModel : IHandle<ChangeUIStateMessage> 
{ 
    public bool UILocked { get { // getter } set { // prop changed code/setter etc... } } 

    public MainViewModel(IEventAggregator aggregator) 
    { 
     aggregator.Subscribe(this); 
    } 

    public void Handle(ChangeUIStateMessage message) 
    { 
     UILocked = message.UILocked; 
    } 
} 

Класс сообщения может быть столь же просто, как:

public class ChangeUIStateMessage 
{ 
    public bool UILocked { get; private set; } 

    public ChangeUIStateMessage(bool uiLocked) 
    { 
     UILocked = uiLocked; 
    } 
} 

Тогда вы можете просто стрелять это с помощью агрегатора из любой виртуальной машины, чтобы заблокировать/разблокировать пользовательский интерфейс

aggregator.Publish(new ChangeUIStateMessage(true)); 

При необходимости вы также можете изменить обработчик, чтобы список объектов, инициировавших блокировку, был сохранен, гарантируя, что пользовательский интерфейс заблокирован до тех пор, пока не завершит работу всех (в случае, если несколько виртуальных машин начинают операцию блокировки/разблокировки одновременно)

Редактировать: Забыл добавить - если элементы управления всплывающим меню находятся в отдельном визуальном дереве (как обычно появляются всплывающие окна), они не будут отключены, что в большинстве случаев работает в ваших интересах (интерактивное всплывающее/заблокированное приложение).

Смежные вопросы