WPF的原生控件并不具备自身的句柄,即使使用偏门的方式获取的结果也都是控件所在窗体的句柄,并不代表该控件本身的资源
,这是由WPF的自身的机制决定的。
csharp
IntPtr hwnd1 = new WindowInteropHelper(this).Handle;
IntPtr hwnd2 = ((HwndSource)PresentationSource.FromVisual(uielement)).Handle;
到此需要了解下Winform与WPF的区别,WPF和winform最大的区别在于WPF底层使用的DirectX,winform底层使用的是GDI+,所以WPF的图形界面上更胜一筹。
当我们直接使用WPF的控件句柄作为OSG等第三方控件的绘制视图区域时,我们会发现视图区域占据了整个窗体,这与上面提到的WPF的原生控件并不具备自身的句柄
的结论一致。
为解决上述问题,在WPF中嵌入第三方控件时,往往需要借助WindowFormsHost控件,使用该控件可以包裹Winform控件,再将Winform的句柄暴露给第三方控件,即可实现在指定区域进行类似OSG视图的绘制。
xml
<WindowsFormsHost Name="FormsHost">
<winform:WebBrowser>
</WindowsFormsHost>
三、WindowFormsHost的置顶缺陷
在WPF中调用windowFormsHost的控件时,由于渲染机制的问题总会出现各种问题,让许多人纠结头疼的便是:
windowFormsHost控件在一个位置时会优先显示,而且完全设置不了顺序,永远在最上边,WPF原生的控件无法对其遮盖,更别说透明了
四、解决WindowFormsHost的置顶问题
经过层层排除和筛选,最终找到一个可行方案:Microsoft.DwayneNeed
。
Microsoft.DwayneNeed.dll
引用xml
<xmlns:interop=clr-namespace:Microsoft.DwayneNeed.Interop;assembly=Microsoft.DwayneNeed>
</xmlns>
在xaml中使用AirspaceDecorator包裹WindowsFormsHost
完整例子如下
xml
<airspace:AirspaceDecorator AirspaceMode="Redirect" IsInputRedirectionEnabled="True" IsOutputRedirectionEnabled="True">
<WindowsFormsHost Name="FormsHost">
<winform:WebBrowser>
</WindowsFormsHost>
</airspace:AirspaceDecorator>