6

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

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

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

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

4

2 回答 2

4

考虑做一个消息过滤器,当你收到 WM_MOUSEWHEEL 时,确定鼠标是否在你的 WPF 控件上。如果是这样,则将消息直接发送到您的 Element 窗口句柄。

像这样的东西:

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;
   }
}
于 2011-05-04T19:08:47.633 回答
1

elementHost.Select() 尝试通过调用这使 MouseWheel 事件为我工作将焦点设置到 ElementHost 。

于 2011-10-19T08:04:52.780 回答