Как отключить события клавиатуры и мыши в части визуального дерева без использования IsEnabled?
У меня есть требование для создания псевдомодальных диалогов в WPF. То есть, по некоторым специфическим (техническим) причинам программное обеспечение не может порождать модальные диалоги. Вместо этого пользователь должен взаимодействовать со "встроенными" модальными диалогами, когда это необходимо.
Я нашел решение, которое очень хорошо работает с MVVM и заботится о Dispatcher и синхронном характере модальных диалогов. Однако я столкнулся с проблемой отключения пользовательского ввода в фоновом графическом интерфейсе. Установка для всех элементов управления значения IsEnabled = false, к сожалению, неприемлема, поскольку она изменяет визуальное состояние фоновых элементов управления (оттенки серого -> плохая читаемость).
Есть ли прямой способ отключить пользовательский ввод (включая фокус и клавиатуру) в фоновом режиме без изменения визуального состояния?
Спасибо за вашу помощь!
4 ответа
У меня есть проект на 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
имущество.
Вы можете установить .IsHitTestVisible
свойство, чтобы отключить любые щелчки мыши для этого элемента управления / окна. Это работает так же, как настройки .IsEnabled
, но без изменения визуального состояния (серые элементы управления).
Я боролся с той же проблемой (также MVVM). Я также использую оверлей UserControl вместо модального всплывающего окна. (В моем случае мне не нравится IsEnabled=false не из-за отключенного стиля, а потому, что переключение IsEnabled затрудняет возврат фокуса клавиатуры.)
Я использую решение наложения (выше) для блокировки действий мыши. И для "другой половины решения" - отключение ввода с клавиатуры - я передаю это в главном окне:
Окно +----------------+ private void Window_PreviewKeyDown(отправитель объекта, | | KeyEventArgs e){ | Прозрачный | if (this.myDialog.Visibility == Visibility.Visible){ | | e.Handled = true; | +----------+ | } | | myDialog | | } | | содержание | | | + ---------- + | | | + ---------------- +
Частичное решение может заключаться в том, чтобы ваш "диалоговый" элемент управления покрывал все окно вашего приложения, но большая его часть была бы прозрачной, с непрозрачным содержимым диалога в середине, например:
+----------------+
| |
| Transparent |
| |
| +----------+ |
| | dialog | |
| | content | |
| +----------+ |
| |
+----------------+
Но это немного взломать.
Чтобы напрямую ответить на ваш вопрос, вы можете использовать Trigger для свойства IsEnabled в ваших элементах управления, чтобы не изменять цвета. Возможно, кто-то с Visual Studio на своем поле может предоставить пример кода.:)
Ответ на ваш комментарий:
Я волнуюсь, что этот ответ становится немного сложным, но вы можете установить свойства IsTabStop и Focusable в false на ваших элементах управления, чтобы получить такое поведение.