2009-07-11 3 views
3

У меня есть требование построить псевдомодальные диалоги в WPF. То есть по некоторым конкретным (техническим) причинам программное обеспечение не разрешено создавать модальные диалоги. Вместо этого пользователь должен взаимодействовать с «встроенными» модальными диалогами, когда это необходимо.Как отключить события клавиатуры и мыши в части визуального дерева без использования IsEnabled?

Я нашел решение, которое хорошо работает с MVVM и заботится о диспетчере и синхронном характере модальных диалогов. Тем не менее, я столкнулся с проблемой отключения пользовательского ввода в фоновом графическом интерфейсе. Установка всех элементов управления на IsEnabled = false, к сожалению, неприемлемо, поскольку он изменяет визуальное состояние элементов управления фоном (оттенки серого -> плохая читаемость).

Есть ли прямой способ отключить ввод пользователя (включая фокус и клавиатуру) в фоновом режиме без изменения визуального состояния?

Благодарим за помощь!

ответ

2

У меня есть проект на github, который предоставляет настраиваемый FrameworkElement, который позволяет отображать модальный контент по основному контенту.

управления может быть использован, как это:

<c:ModalContentPresenter IsModal="{Binding DialogIsVisible}"> 
    <TabControl Margin="5"> 
      <Button Margin="55" 
        Padding="10" 
        Command="{Binding ShowModalContentCommand}"> 
       This is the primary Content 
      </Button> 
     </TabItem> 
    </TabControl> 

    <c:ModalContentPresenter.ModalContent> 
     <Button Margin="75" 
       Padding="50" 
       Command="{Binding HideModalContentCommand}"> 
      This is the modal content 
     </Button> 
    </c:ModalContentPresenter.ModalContent> 

</c:ModalContentPresenter> 

Особенности:

  • Отображает произвольное содержимое.
  • Не отключает основной контент, пока отображается модальный контент.
  • Отключает доступ к основному контенту для мыши и клавиатуры, пока отображается модальное содержимое.
  • Является только модальным для содержания, которое он покрывает, а не для всего приложения.
  • может использоваться в дружественном для MVVM способом путем привязки к объекту IsModal.
0

Частичное решение может быть, чтобы сделать элемент управления «диалог» охватывает окно вашего приложения полностью, но есть большая часть его быть прозрачным, непрозрачным диалогового содержания в середине, как:

+----------------+ 
|    | 
| Transparent | 
|    | 
| +----------+ | 
| | dialog | | 
| | content | | 
| +----------+ | 
|    | 
+----------------+ 

Но, что это немного взломать.

Чтобы напрямую решить свой вопрос, вы можете использовать триггер на свойстве IsEnabled на своих элементах управления, чтобы цвета не менялись. Возможно, кто-то с Visual Studio на своем поле может предоставить образец кода. :)

Ответ на ваш комментарий:

Я беспокоюсь, что этот ответ становится немного сложнее, но вы можете установить IsTabStop и фокусируемое свойство к ложному над элементами управления, чтобы получить такое поведение.

+0

Благодарим за отзыв! К сожалению, добавление прозрачного слоя в приложение - это только половина решения (вот где я сейчас). Моя проблема - отключить фокус клавиатуры в слое под прозрачным слоем. Можно использовать вкладки для элементов управления, которые находятся ниже прозрачной поверхности :-) –

+0

Вы можете установить свойства IsTabStop и Focusable в false на своих элементах управления, чтобы получить это поведение ... хотя, я беспокоюсь, что это решение не очень элегантно. – exclsr

3

Я боролся с той же проблемой (также MVVM). Я также использую overlay UserControl вместо модального всплывающего окна. (В моем случае я не люблю IsEnabled = false не из-за отключенного стиля, а потому, что переключение IsEnabled затрудняет восстановление фокуса клавиатуры.)

Я использую наложенное решение (выше) для блокировки действия мыши , А за «вторую половину раствора» - -disabling ввод с клавиатуры - Я вручая это в главном окне:

 

Window 
+----------------+ private void Window_PreviewKeyDown(object sender, 
|    |          KeyEventArgs e){ 
| Transparent |  if (this.myDialog.Visibility == Visibility.Visible){ 
|    |   e.Handled = true; 
| +----------+ |  } 
| | myDialog | | } 
| | content | | 
| +----------+ | 
|    | 
+----------------+ 

4

Вы можете установить свойство .IsHitTestVisible отключить все кликами мыши к этому элементу управления/окна. Это работает так же, как настройки .IsEnabled, но без изменения визуального состояния (серые элементы управления).

+0

Это только блокирует события мыши. Вы все еще можете использовать клавиатуру для запуска событий из элементов управления фона. –