Search code examples
.netwpfisenabled

How to disable keyboard and mouse events in a part of the visual tree without using IsEnabled?


I've the requirement to build pseudo-modal dialogs in WPF. That is, for some specific (technical) reasons the software is not allowed to spawn modal dialogs. Instead, the user should interact with "embedded" modal dialogs when necessary.

I found a solution that works pretty well with MVVM and takes care of the Dispatcher and the synchronous character of modal dialogs. However, I am facing a problem with disabling the user input in the background GUI. Setting all controls to IsEnabled = false is unfortunately not acceptable since it changes the visual state of the background controls (shades of grey ->bad readability).

Is there a straight forward way to disable the user input (including focus and keyboard) in the background without changing the visual state?

Thanks for your help!


Solution

  • I have a project on github which provides a custom FrameworkElement that allows you to display modal content over the primary content.

    The control can be used like this:

    <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>
    

    Features:

    • Displays arbitrary content.
    • Does not disable the primary content whilst the modal content is being displayed.
    • Disables mouse and keyboard access to the primary content whilst the modal content is displayed.
    • Is only modal to the content it is covering, not the entire application.
    • can be used in an MVVM friendly way by binding to the IsModal property.