如何在不使用 IsEnabled 的情况下禁用可视化树的一部分中的键盘和鼠标事件?

发布于 2024-07-26 22:15:08 字数 319 浏览 6 评论 0原文

我需要在 WPF 中构建伪模式对话框。 也就是说,由于某些特定(技术)原因,不允许软件生成模式对话框。 相反,用户应该在必要时与“嵌入式”模式对话框进行交互。

我找到了一个与 MVVM 配合得很好的解决方案,并且可以处理调度程序和模式对话框的同步特性。 但是,我遇到了在后台 GUI 中禁用用户输入的问题。 遗憾的是,将所有控件设置为 IsEnabled = false 是不可接受的,因为它会更改背景控件的视觉状态(灰色阴影 -> 可读性差)。

是否有一种直接的方法可以在后台禁用用户输入(包括焦点和键盘)而不改变视觉状态?

感谢您的帮助!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

〃安静 2024-08-02 22:15:09

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

特点:

  • 显示任意内容。
  • 显示模态内容时不禁用主要内容。
  • 显示模态内容时禁用鼠标和键盘访问主要内容。
  • 仅适用于其所涵盖的内容,而不适用于整个应用程序。
  • 可以通过绑定到 IsModal 属性以 MVVM 友好的方式使用。

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.
爱给你人给你 2024-08-02 22:15:09

部分解决方案可能是让您的“对话框”控件覆盖整个应用程序的窗口,但其中大部分是透明的,中间有不透明的对话框内容,例如:

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

但是,这有点像黑客。

要直接解决您的问题,您可以在控件的 IsEnabled 属性上使用触发器来防止颜色发生变化。 也许带有 Visual Studio 的人可以提供代码示例。 :)

对您的评论的回应:

我担心这个答案会变得有点棘手,但您可以在控件上将 IsTabStop 和 Focusable 属性设置为 false 以获得该行为。

A partial solution could be to make your "dialog" control cover your entire application's Window, but have most of it be transparent, with opaque dialog content in the middle, like:

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

But, that is a bit of a hack.

To directly address your question, you can use a Trigger on the IsEnabled property on your controls to keep the colors from changing. Perhaps someone with Visual Studio on their box can provide a code sample. :)

Response to your comment:

I worry that this answer is getting a bit tricky, but you can set the IsTabStop and Focusable properties to false on your controls to get that behavior.

风和你 2024-08-02 22:15:08

您可以设置 .IsHitTestVisible 属性来禁用对该控件/窗口的任何鼠标单击。 这与设置 .IsEnabled 的工作方式相同,但没有视觉状态更改(灰色控件)。

You can set the .IsHitTestVisible property to disable any mouseclicks to that control/window. This works the same as settings .IsEnabled, but without the visual state change (grey controls).

毁梦 2024-08-02 22:15:08

我一直在努力解决同样的问题(也是 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  |  |
|  +----------+  |
|                |
+----------------+

I've been struggling with the same issue (also MVVM). I'm also using a UserControl overlay instead of a modal popup.
(In my case, I dislike IsEnabled=false not because of the disabled style, but because toggling IsEnabled makes it hard to get keyboard focus back.)

I'm using the overlay solution (above) for blocking mouse action. And for the "other half of the solution" - -disabling keyboard input -- I'm handing this in the main window:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文