- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在 WPF 应用程序中有一个 WinForms 控件。幸运的是,在 WPF 中,鼠标滚轮事件通常由鼠标光标下的控件处理……但如果它是 WinForms 控件,我必须先单击该控件才能为其提供键盘焦点。如何绕过此行为并在 WinForms 控件没有焦点时将鼠标滚轮事件发送到它?
(注意:MouseWhee
l 和 PreviewMouseWheel
事件似乎不适用于 WindowsFormsHost。如果您在WindowsFormsHost 的父级,当鼠标位于非 WPF 控件之上时,它不会被调用。显然,WinForms 控件也没有获得 MouseWheel
事件;该事件似乎完全消失了。)
最佳答案
一个可能的解决方案是处理所有 WM_MOUSEWHEEL
消息并手动为未获得焦点的控件引发 MouseWheel
事件。我的附加行为实现了这个想法:
public static class CaptureMouseWheelWhenUnfocusedBehavior
{
private static readonly HashSet<WindowsFormsHost> TrackedHosts =
new HashSet<WindowsFormsHost>();
private static readonly System.Windows.Forms.IMessageFilter MessageFilter =
new MouseWheelMessageFilter();
private sealed class MouseWheelMessageFilter : System.Windows.Forms.IMessageFilter
{
[DllImport("User32.dll"), SuppressUnmanagedCodeSecurity]
private static extern IntPtr WindowFromPoint(System.Drawing.Point point);
private static System.Drawing.Point LocationFromLParam(IntPtr lParam)
{
int x = (int)((((long)lParam) >> 0) & 0xffff);
int y = (int)((((long)lParam) >> 16) & 0xffff);
return new System.Drawing.Point(x, y);
}
private static bool ConsiderRedirect(WindowsFormsHost host)
{
var control = host.Child;
return control != null &&
!control.IsDisposed &&
control.IsHandleCreated &&
control.Visible &&
!control.Focused;
}
private static int DeltaFromWParam(IntPtr wParam)
{
return (short)((((long)wParam) >> 16) & 0xffff);
}
private static System.Windows.Forms.MouseButtons MouseButtonsFromWParam(IntPtr wParam)
{
const int MK_LBUTTON = 0x0001;
const int MK_MBUTTON = 0x0010;
const int MK_RBUTTON = 0x0002;
const int MK_XBUTTON1 = 0x0020;
const int MK_XBUTTON2 = 0x0040;
int buttonFlags = (int)((((long)wParam) >> 0) & 0xffff);
var buttons = System.Windows.Forms.MouseButtons.None;
if(buttonFlags != 0)
{
if((buttonFlags & MK_LBUTTON) == MK_LBUTTON)
{
buttons |= System.Windows.Forms.MouseButtons.Left;
}
if((buttonFlags & MK_MBUTTON) == MK_MBUTTON)
{
buttons |= System.Windows.Forms.MouseButtons.Middle;
}
if((buttonFlags & MK_RBUTTON) == MK_RBUTTON)
{
buttons |= System.Windows.Forms.MouseButtons.Right;
}
if((buttonFlags & MK_XBUTTON1) == MK_XBUTTON1)
{
buttons |= System.Windows.Forms.MouseButtons.XButton1;
}
if((buttonFlags & MK_XBUTTON2) == MK_XBUTTON2)
{
buttons |= System.Windows.Forms.MouseButtons.XButton2;
}
}
return buttons;
}
public bool PreFilterMessage(ref System.Windows.Forms.Message m)
{
const int WM_MOUSEWHEEL = 0x020A;
if(m.Msg == WM_MOUSEWHEEL)
{
var location = LocationFromLParam(m.LParam);
var hwnd = WindowFromPoint(location);
foreach(var host in TrackedHosts)
{
if(!ConsiderRedirect(host)) continue;
if(hwnd == host.Child.Handle)
{
var delta = DeltaFromWParam(m.WParam);
{
// raise event for WPF control
var mouse = InputManager.Current.PrimaryMouseDevice;
var args = new MouseWheelEventArgs(mouse, Environment.TickCount, delta);
args.RoutedEvent = WindowsFormsHost.MouseWheelEvent;
host.RaiseEvent(args);
}
{
// raise event for winforms control
var buttons = MouseButtonsFromWParam(m.WParam);
var args = new System.Windows.Forms.MouseEventArgs(
buttons, 0, location.X, location.Y, delta);
var method = typeof(System.Windows.Forms.Control).GetMethod(
"OnMouseWheel",
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic);
method.Invoke(host.Child, new object[] { args });
}
return true;
}
}
}
return false;
}
}
public static bool GetIsEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(IsEnabledProperty);
}
public static void SetIsEnabled(DependencyObject obj, bool value)
{
obj.SetValue(IsEnabledProperty, value);
}
public static readonly DependencyProperty IsEnabledProperty =
DependencyProperty.RegisterAttached(
"IsEnabled",
typeof(bool),
typeof(CaptureMouseWheelWhenUnfocusedBehavior),
new PropertyMetadata(false, OnIsEnabledChanged));
private static void OnIsEnabledChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
var wfh = o as WindowsFormsHost;
if(wfh == null) return;
if((bool)e.NewValue)
{
wfh.Loaded += OnHostLoaded;
wfh.Unloaded += OnHostUnloaded;
if(wfh.IsLoaded && TrackedHosts.Add(wfh))
{
if(TrackedHosts.Count == 1)
{
System.Windows.Forms.Application.AddMessageFilter(MessageFilter);
}
}
}
else
{
wfh.Loaded -= OnHostLoaded;
wfh.Unloaded -= OnHostUnloaded;
if(TrackedHosts.Remove(wfh))
{
if(TrackedHosts.Count == 0)
{
System.Windows.Forms.Application.RemoveMessageFilter(MessageFilter);
}
}
}
}
private static void OnHostLoaded(object sender, EventArgs e)
{
var wfh = (WindowsFormsHost)sender;
if(TrackedHosts.Add(wfh))
{
if(TrackedHosts.Count == 1)
{
System.Windows.Forms.Application.AddMessageFilter(MessageFilter);
}
}
}
private static void OnHostUnloaded(object sender, EventArgs e)
{
var wfh = (WindowsFormsHost)sender;
if(TrackedHosts.Remove(wfh))
{
if(TrackedHosts.Count == 0)
{
System.Windows.Forms.Application.RemoveMessageFilter(MessageFilter);
}
}
}
}
它可以在 XAML 中使用:
<WindowsFormsHost namespace:CaptureMouseWheelWhenUnfocusedBehavior.IsEnabled="True" />
和代码隐藏:
CaptureMouseWheelWhenUnfocusedBehavior.SetIsEnabled(host, true);
更新:添加代码以引发 WinForms 控件的事件
关于.net - 如何将鼠标滚轮事件传输到 WindowsFormsHost?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14246483/
看来 WindowsFormsHost 控件设置为显示在顶部。有什么方法可以更改其 z 顺序以允许同一窗口上的其他 WPF 控件在 WindowsFormsHost 控件顶部可见? 最佳答案 不幸的是
我在 WPF 应用程序中有一个 WinForms 控件。幸运的是,在 WPF 中,鼠标滚轮事件通常由鼠标光标下的控件处理……但如果它是 WinForms 控件,我必须先单击该控件才能为其提供键盘焦点。
好的,我不确定我是否理解这应该如何工作,但在我的应用程序中,我已将按键手势 (Ctrl+K) 绑定(bind)到 RoutedCommand。无论我在我的应用程序中关注的哪个位置,组合键都有效,除非我
我在 WPF 窗口内的 WindowsFormsHost 控件中嵌入了一个 SWF 对象。 我想在 swf 影片上添加一个工具栏。 我下面的代码片段的问题是,当新的子项被添加到主机控件时(或者电影被加
在我的 wpf 应用程序中,我正在尝试使用 Windows 窗体控件....但是我收到一个错误,即错误 找不到类型“WindowsFormsHost”。确认您没有缺少程序集引用并且所有引用的程序集都已
有没有办法延迟 WindowsFormsHost 的绘制?它托管在 WPF 中。 它承载一个 COM 对象,它是一个 ESRI ArcEngine AxTocControl。从视觉上看,它看起来像一个
我使用 WindowsFormsHost 控件在 WPF 浏览器应用程序中嵌入了一个 Windows 窗体应用程序,但窗体的大小总是有点短(大约 10 像素)。在调试过程中,我注意到表单的高度和宽度比
因此,我的 WPF 应用程序(托管 Dundas 图表)中有一个 WindowsFormsHost 控件,我想在其上放置一个 ContextMenu。 我可以成功地将 ContextMenu 附加到任
我正在尝试在 WPF 的 WindowsFormsHost 控件中托管 ILPanel。这是我的代码: XAML: 代
我在 WPF 弹出窗口中托管 windowsforms 控件。问题如下: 如果我使 StaysOpen=False 无法与 winform 控件交互。 StaysOpen 为 false 是必需的,因
因为 WPF 没有允许显示多个月份的月历,所以我尝试在 WindowsFormsHost 中使用经典的 WindowsForms MonthCalendar。在“普通”WPF 窗口中执行此操作效果很好
我有一个 WPF 窗口,它需要多个 WindowsFormHost 控件。我注意到,如果我像这样对控件进行建模,那么异常不会冒泡到表面,而是会默默地进行处理,即仅使用 SharpDevelop 的调试
我在 WPF WindowsFormsHost 中有 Winforms 控件。Winforms 控件是被动的,不能处理任何鼠标事件。鼠标事件应该像往常一样从 WPF 可视化树中最内部的 WPF 控件引
在我的 WPF 中,我有一个包含 WindowsFormsHost 的网格,它将承载一个 .exe。我的 .xaml 代码是: 还有我的客服
如何设置 z-index windowsformshost 它们并不总是位于 WPF 元素的顶部? 最佳答案 根据 MSDN (Layout Considerations for the Window
我有一个 WPF 应用程序,它使用 WindowsFormsHost 控件来承载 Windows.Forms 控件。 我试图实现 MouseWheel 事件 - 但似乎 MouseWheel 事件从未
我有一个 View 模型,我在其中以这种方式创建我的窗口窗体: System.Windows.Forms.DataVisualization.Charting.Chart chart = new Sy
在 WPF 应用程序中,我创建了 WindowsFormsHost 并想在其中插入一个包含 COM/Activex 的 Form控制。但后来我得到: A first chance exception
我正在使用以下方法将 WINFORM 图表添加到我的 WPF 项目中 System.Windows.Forms.Integration.WindowsFormsHost 我正在尝试解决“领空”呈现问
所以我遇到了一个奇怪的错误...我按照一些步骤在我的 WPF C# 应用程序中创建了一个 CircularProgressBar。它在我的台式机上运行良好,但在我的笔记本电脑上运行不正常。 我创建了一
我是一名优秀的程序员,十分优秀!