【问题标题】:Keep Mouse Events bubbling from WindowsFormsHost on保持鼠标事件从 WindowsFormsHost 冒泡
【发布时间】:2014-11-13 12:48:22
【问题描述】:

我在 WPF WindowsFormsHost 中有 Winforms 控件。 Winforms 控件是被动的,不能处理任何鼠标事件。 鼠标事件应该像往常一样从 WPF 可视化树中最内部的 WPF 控件引发,因此是 WindowsFormsHost(或下一个)。但是根本没有触发任何事件。

我应该如何配置 WindowsFormsHost、Winforms 控件来实现这一点?

备注:KeyDown 和 KeyUp 的行为符合预期。但鼠标事件不会,如下面的 Snoop 屏幕截图所示:

【问题讨论】:

  • Winforms 几乎没有改变 Windows 生成和路由通知的方式,而不仅仅是键盘快捷键处理和将某些消息从父级返回给子级。 MouseWheel 对父级起泡,其余的则不会。 WindowsFormsHost 没有做任何改变。所以这完全是意料之中的。如果控件不应该接收输入事件,则应将其 Enabled 属性设置为 false。你可能也不喜欢这样:)
  • 谢谢!请解释一下...如果您用简单的 WPF UserControl 替换 WindowsFormsHost,那么冒泡会起作用,并且 MouseDown 事件会冒泡并在上升过程中引发订阅者的事件处理程序。似乎 Winforms 控件为自己保留了鼠标事件,并且没有将事件转发给它的主机。对吗?

标签: c# wpf winforms event-bubbling windowsformshost


【解决方案1】:

确实,Winforms 控件为自己保留鼠标事件,并且不会将事件转发给它的宿主。解决方案是订阅 winforms MouseDown 事件并以编程方式生成 Routed 事件。

我按如下方式覆盖了 WindowsFormsHost,它摇摆不定:

(备注:行为可能更灵活)

public class ExtendedWindowsFormsHost : WindowsFormsHost
{
    public ExtendedWindowsFormsHost()
    {
        ChildChanged += OnChildChanged;
    }

    private void OnChildChanged(object sender, ChildChangedEventArgs childChangedEventArgs)
    {
        var previousChild = childChangedEventArgs.PreviousChild as Control;            
        if (previousChild != null)
        {
            previousChild.MouseDown -= OnMouseDown;
        }
        if (Child != null)
        {
            Child.MouseDown += OnMouseDown;
        }
    }

    private void OnMouseDown(object sender, MouseEventArgs mouseEventArgs)
    {
        MouseButton? wpfButton = ConvertToWpf(mouseEventArgs.Button);
        if (!wpfButton.HasValue)
            return;

        RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, wpfButton.Value)
        {
            RoutedEvent = Mouse.MouseDownEvent,
            Source = this,
        });
    }

    private MouseButton? ConvertToWpf(MouseButtons winformButton)
    {
        switch (winformButton)
        {
            case MouseButtons.Left:
                return MouseButton.Left;
            case MouseButtons.None:
                return null;
            case MouseButtons.Right:
                return MouseButton.Right;
            case MouseButtons.Middle:
                return MouseButton.Middle;
            case MouseButtons.XButton1:
                return MouseButton.XButton1;
            case MouseButtons.XButton2:
                return MouseButton.XButton2;
            default:
                throw new ArgumentOutOfRangeException("winformButton");
        }
    }
}

【讨论】:

  • 能否请您添加此文件的标题?如果某些参数属于 Windows 窗体或输入,则会出现混淆。
  • 以下标题应该可以工作:使用 System.Windows.Forms;使用 System.Windows.Forms.Integration;使用 System.Windows.Input; + 完全合格的 System.Windows.Forms.MouseButtons
猜你喜欢
  • 2019-07-11
  • 1970-01-01
  • 2011-08-05
  • 1970-01-01
  • 1970-01-01
  • 2011-10-20
  • 2011-08-23
  • 1970-01-01
  • 2021-08-14
相关资源
最近更新 更多