Как отключить события клавиатуры и мыши в части визуального дерева без использования IsEnabled? - PullRequest
3 голосов
/ 11 июля 2009

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

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

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

Спасибо за вашу помощь!

Ответы [ 4 ]

4 голосов
/ 09 октября 2011

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

3 голосов
/ 31 июля 2009

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

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


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

2 голосов
/ 01 июля 2012

У меня есть проект на 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 голосов
/ 12 июля 2009

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

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

Но это что-то вроде хака.

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

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

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

...