Держите события мыши всплывающими из WindowsFormsHost на
У меня есть контроль Winforms в WPF WindowsFormsHost. Элемент управления Winforms пассивен и не должен обрабатывать события мыши. События мыши должны вызываться как обычно из самого внутреннего элемента управления WPF в визуальном дереве WPF, то есть из WindowsFormsHost (или следующего). Но никакое событие не вызвано вообще.
Как мне настроить WindowsFormsHost, элемент управления Winforms, чтобы добиться этого?
Замечание: KeyDown и KeyUp ведут себя как положено. Но Mouse Mouse не делают этого, как показано на следующем снимке экрана Snoop:
1 ответ
Действительно, элемент управления Winforms сохраняет событие мыши для себя и не передает событие своему хосту. Решение состоит в том, чтобы подписаться на событие MouseDown winforms и программно генерировать Routed Event.
Я переписал 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");
}
}
}