当托管在WinForms容器中时,WPF ScrollViewer不会接收鼠标事件

当托管在WinForms容器中时,WPF ScrollViewer不会接收鼠标事件,wpf,winforms,winforms-interop,Wpf,Winforms,Winforms Interop,我们有一个WinForms应用程序,正在逐步转换为WPF。此时,应用程序的主窗体是一个窗体(WinForms),其中包含内置于WPF中的垂直侧栏。侧栏位于ElementHost控件中 侧边栏由包含其他控件的ScrollViewer组成。问题是,当焦点在WinForms aera中的某个地方,我在ScrollViewer上使用鼠标滚轮时,它不会滚动 这与WPF/WinForms集成有关,因为在100%WPF项目中,即使焦点在另一个控件上,ScrollViewer也会对鼠标滚轮作出反应 解决此问题的

我们有一个WinForms应用程序,正在逐步转换为WPF。此时,应用程序的主窗体是一个窗体(WinForms),其中包含内置于WPF中的垂直侧栏。侧栏位于ElementHost控件中

侧边栏由包含其他控件的ScrollViewer组成。问题是,当焦点在WinForms aera中的某个地方,我在ScrollViewer上使用鼠标滚轮时,它不会滚动

这与WPF/WinForms集成有关,因为在100%WPF项目中,即使焦点在另一个控件上,ScrollViewer也会对鼠标滚轮作出反应


解决此问题的正确方法是什么?

考虑执行消息筛选,当您收到WM_MOUSEWHEEL时,确定鼠标是否位于WPF控件上方。如果是这样,则直接将消息发送到元素窗口句柄

大概是这样的:

System.Windows.Forms.Application.AddMessageFilter( new MouseWheelMessageFilter( YourElementInsideAnElementHost ) );
当您超出范围时,不要忘记调用RemoveMessageFilter

public class MouseWheelMessageFilter : IMessageFilter
{
   private const int WM_MOUSEWHEEL = 0x020A;
   private FrameworkElement _element;

   [DllImport("user32.dll")]
   public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

   public MouseWheelMessageFilter(FrameworkElement element)
   {
       _element = element;
   }

   public bool PreFilterMessage(ref Message m)
   {
       if (m.Msg == WM_MOUSEWHEEL)
       {
           Rect rect = new Rect(0, 0, _element.ActualWidth, _element.ActualHeight);
           Point pt = Mouse.GetPosition(_element);

           if (rect.Contains(pt))
           {
               HwndSource hwndSource = (HwndSource)HwndSource.FromVisual(_element);
               SendMessage(hwndSource.Handle, m.Msg, m.WParam, m.LParam);
               return true;
           }
       }

       return false;
   }
}

通过调用
ElementHost.Select()
这使得鼠标轮活动对我来说很有效