Сохранять всплывающие события мыши с WindowsFormsHost на

У меня есть элемент управления Winforms в WPF WindowsFormsHost. Элемент управления Winforms пассивен и не должен обрабатывать какие-либо события мыши. События мыши должны вызываться как обычно из самого внутреннего элемента управления WPF в визуальном дереве WPF, поэтому WindowsFormsHost (или следующий). Но вообще никакое событие не запускается.

Как мне настроить WindowsFormsHost, элемент управления Winforms, чтобы этого добиться?

Примечание: KeyDown и KeyUp работают должным образом. Но событий мыши нет, как показано на следующем снимке экрана Snoop:

введите описание изображения здесь


person jeromerg    schedule 13.11.2014    source источник
comment
Winforms мало что делает для изменения способа генерации и маршрутизации уведомлений Windows, помимо обработки сочетаний клавиш и отражения определенных сообщений от родителя обратно к потомку. MouseWheel переходит к родительскому объекту, остальные - нет. WindowsFormsHost ничего не делает, чтобы это изменить. Так что это вполне ожидаемо. Если элемент управления не должен получать входные события, его свойство Enabled должно иметь значение false. Тебе это, наверное, тоже не нравится :)   -  person Hans Passant    schedule 13.11.2014
comment
Спасибо! Пожалуйста, объясните ... если вы замените WindowsFormsHost на простой WPF UserControl, то всплытие будет работать, и событие MouseDown всплывает вверх и поднимает обработчики событий подписчика на своем пути. Кажется, что Winforms Control сохраняет событие мыши для себя и не пересылает событие своему хосту. Это правильно?   -  person jeromerg    schedule 13.11.2014


Ответы (1)


Действительно, Winforms Control сохраняет событие мыши для себя и не пересылает событие своему хосту. Решение состоит в том, чтобы подписаться на событие Winforms MouseDown и программно сгенерировать перенаправленное событие.

Я переопределил 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");
        }
    }
}
person jeromerg    schedule 13.11.2014
comment
Не могли бы вы добавить заголовки этого файла? Существует путаница с некоторыми параметрами, если они принадлежат Windows Forms или Input. - person Sorush; 07.12.2018
comment
следующий заголовок должен работать: using System.Windows.Forms; using System.Windows.Forms.Integration; using System.Windows.Input; + полностью квалифицированный System.Windows.Forms.MouseButtons - person niyou; 08.10.2020