Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keep Mouse Events bubbling from WindowsFormsHost on

I have Winforms control within a WPF WindowsFormsHost. The Winforms control is passive and must not handle any mouse event. Mouse events should be raised as usual from the most inner WPF control in the WPF visual tree, so the WindowsFormsHost (or the next one). But no event is triggered at all.

How should I configure the WindowsFormsHost, the Winforms control, in order to achieve this?

Remark: KeyDown and KeyUp behave as expected. But Mouse Events don't, as illustrated by the following Snoop screenshot:

enter image description here

like image 860
jeromerg Avatar asked Oct 30 '25 14:10

jeromerg


1 Answers

Indeed the Winforms Control keeps the mouse event for himself and doesn't forward the event to its host. The solution is to subscribe to the winforms MouseDown event and generate programmatically the Routed Event.

I overrided the WindowsFormsHost as following and it rocks:

(remark: a behavior may be more flexible)

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");
        }
    }
}
like image 135
jeromerg Avatar answered Nov 01 '25 05:11

jeromerg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!