我有一个Winforms控件嵌在WPF的WindowsFormsHost中。
Winforms控件是被动的,不应该处理任何鼠标事件。
鼠标事件应该像通常一样从WPF可视树中最内层的控件触发,因此是WindowsFormsHost(或下一个)。
但是没有事件被触发。
为了实现这一点,我应该如何配置WindowsFormsHost以及Winforms控件呢?
注:KeyDown和KeyUp的行为符合预期。但是,正如以下Snoop截图所示,鼠标事件并不会触发:
Winforms控件会独占鼠标事件,不会将事件转发给其宿主。解决方案是订阅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");
}
}
}