【问题标题】:ElementHost blocks mouse eventsElementHost 阻止鼠标事件
【发布时间】:2015-10-08 21:37:47
【问题描述】:

注意:我正在尝试解决鼠标问题,而不是已经解决的键盘问题

所以我正在创建一个 Visual Studio 2015 扩展,在选项页面上工作。

我正在使用 WPF,因此我使用 ElementHost 来托管 UserControl。起初它没有收到键盘事件,所以我在以下位置实现了解决方案:

WPF TextBox not accepting Input when in ElementHost in Window Forms

解决方案的简要介绍:

A) 在 UserControl 的 Loaded 事件上,我会这样做:

var s = HwndSource.FromVisual(this) as HwndSource;
s?.AddHook(ChildHwndSourceHook);

B) 在 ChildHwndSourceHook() 中,我执行以下操作:

static IntPtr ChildHwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    if (msg == WM_GETDLGCODE)
    {
        handled = true;
        return new IntPtr(DLGC_WANTCHARS | DLGC_WANTARROWS | DLGC_HASSETSEL | DLGC_WANTTAB);
    }
    return IntPtr.Zero;
}

但是,现在鼠标悬停的事件似乎被忽略了,因为光标在文本框或网格拆分器上移动时不会改变,即使在我创建的新 Windows 上也是如此。 偶尔,虽然鼠标事件确实有效,但会继续有效,直到我移动到另一个页面或关闭对话框。这是最奇怪的部分。

我已经尝试了所有方法,并且整天都在谷歌上搜索,但我无法理解为什么点击可以正常工作,但鼠标悬停事件似乎没有被注册。

我确实尝试过删除消息处理程序,然后打开一个窗口,但似乎一旦添加了处理程序,删除它就不会解决任何问题。

有谁知道如何让鼠标悬停在事件上以在我的控件上工作?非常感谢!

【问题讨论】:

  • 一段代码没有做它应该有用的事情。

标签: wpf winforms mouseover visual-studio-extensions elementhost


【解决方案1】:

我发现使用创建者 Viasfora 使用的方法取得了成功。您可以在GitHub repo here 上查看代码。特别是,查看 TextObfuscationDialog 及其托管方式。我认为 VS 扩展文档可能有问题,因为我遇到了与您相同的问题。

编辑:

我创建了一个示例项目来展示这个方法确实有效(我现在在我自己的 2 个扩展中使用它)。希望这个工作代码可以让您更轻松地在自己的项目中实现它。

您可以从我的OneDrive here下载源代码。

UIElementDialogPageon MSDN 说:

提供 Windows Presentation Foundation (WPF) 的无缝托管 运行 IsDialogMessage 样式的本机对话框中的内容 消息循环。此类启用进入和退出 WPF 子项的选项卡 窗口句柄 (HWND),并在 WPF 中启用键盘导航 子 HWND。

因此,虽然ElementHost 在普通/WinForms DialogPage 的消息循环中无法正常运行,但 UIElementDialogPage 会。有许多具有 UIElement* 或类似前缀的类 - 它们用于帮助将 VS 的旧代码从 Windows 窗体迁移到 WPF。

【讨论】:

  • 对不起,您的回答实际上根本不起作用。我仔细查看了这段代码,您所做的只是将我实现的原始答案包装到派生的 ElementHost 类中。它对鼠标不改变问题没有帮助。 :(
  • 我看看能不能用你可以使用的工作代码创建一个新项目。
  • @ChrisBordeman 我已经用一个工作项目编辑了我的答案。您应该能够将文件直接带到您的项目中并重构它们以适应您的命名空间。我还添加了一个屏幕截图来显示此包装器产生的正确鼠标行为。
  • 好的,您的示例有效,因此您获得了信用,谢谢。但是,您所做的只是从 UIElementDialogPage 派生 TextObfuscationDialog 而不是通常的类。就是这样。我真希望你没有浪费我的时间把我指向 Github,在那里你做了一些完全不同的事情,完全重新实现了 UIElementDialogPage。也就是说,我自己尝试从 Shell UIElementDialogPage 派生,但没有正确,因为我认为 Winforms 生成的代码一定没有使用新的派生。我使用了一个普通的源文件,如果它仍然不起作用,会告诉你。谢谢!
  • 我大吃一惊。它仍然不起作用。我从 UserControl 派生,在选项页面上我从 UIElementDialogPage 派生。这很简单,但是当我将鼠标悬停在 TextBox 上时光标不会改变。 ;(
猜你喜欢
  • 2012-12-17
  • 1970-01-01
  • 2013-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多