在 WindowsFormsHost 之上呈现 WPF 控件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5978917/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Render WPF control on top of WindowsFormsHost
提问by Vitalij
I know that default WPF behavior is to render WPF controls and then on top render WinForms, but are there any way to render WPF on top of WindowsFormsHost
?
我知道默认的 WPF 行为是呈现 WPF 控件,然后在顶部呈现 WinForms,但是有没有办法在顶部呈现 WPF WindowsFormsHost
?
Edit: I have found a temp hack as well. When wpf control overlaps WindowsFormsHost
, I change the size of the WindowsFormsHost
(This only works when you have rectangular object which overlaps, doesn't work for other shapes.)
编辑:我也发现了一个临时黑客。当 wpf 控件重叠时WindowsFormsHost
,我更改了的大小WindowsFormsHost
(这只适用于重叠的矩形对象,不适用于其他形状。)
采纳答案by CodeNaked
This "airspace" issue is suppose to be fixedin WPF vNext. There are a couple solutions out there, such as here, here, and here.
这个“空域”问题应该在 WPF vNext 中得到修复。有几种解决方案,例如此处、此处和此处。
One way to do this is to host the WPF content in a transparent Popup or Window, which overlays the Interop content.
一种方法是将 WPF 内容托管在透明的弹出窗口或窗口中,它覆盖互操作内容。
回答by chris84948
Late to the party, I know, but I recently came across this issue using a WebBrowser control.
我知道聚会迟到了,但我最近在使用 WebBrowser 控件时遇到了这个问题。
The final fix was to create a screenshot of the web browser whenever I hosted a modal dialog over the top. Since this was a little fiddly, I turned it into a Github project, hopefully this helps a little -
最终的解决方法是每当我在顶部托管一个模态对话框时创建 Web 浏览器的屏幕截图。由于这有点繁琐,我把它变成了一个 Github 项目,希望这会有所帮助 -
https://github.com/chris84948/AirspaceFixer
https://github.com/chris84948/AirspaceFixer
(It's on Nuget too, under AirspaceFixer)
(它也在 Nuget 上,在 AirspaceFixer 下)
Once you have the project all you need to do is this
一旦你有了项目,你需要做的就是这个
xmlns:asf="clr-namespace:AirspaceFixer;assembly=AirspaceFixer"
<asf:AirspacePanel FixAirspace="{Binding FixAirspace}">
<WebBrowser x:Name="Browser" />
</asf:AirspacePanel>
Where FixAirspace
is the dependency property that switches from the "real" view of the content, to the screenshot or "fake" view.
FixAirspace
从内容的“真实”视图切换到屏幕截图或“假”视图的依赖属性在哪里。
回答by AVIDeveloper
Here's a link to the best answer I've seen on this subject so far: Can I overlay a WPF window on top of another?
这是迄今为止我在该主题上看到的最佳答案的链接: 我可以将 WPF 窗口叠加在另一个窗口之上吗?
回答by sky-dev
Try this on for size:
试试这个尺寸:
<hacks:AirspaceOverlay>
<hacks:AirspaceOverlay.OverlayChild>
<Canvas ToolTip = "A tooltip over a DirectX surface" Background="#01000000" Name="Overlay" />
</hacks:AirspaceOverlay.OverlayChild>
<controls:OpenGLControlWrappingWindowsFormsHost />
</hacks:AirspaceOverlay>
// Adapted from http://blogs.msdn.com/b/pantal/archive/2007/07/31/managed-directx-interop-with-wpf-part-2.aspx & http://www.4mghc.com/topics/69774/1/in-wpf-how-can-you-draw-a-line-over-a-windowsformshost
public class AirspaceOverlay : Decorator
{
private readonly Window _transparentInputWindow;
private Window _parentWindow;
public AirspaceOverlay()
{
_transparentInputWindow = CreateTransparentWindow();
_transparentInputWindow.PreviewMouseDown += TransparentInputWindow_PreviewMouseDown;
}
public object OverlayChild
{
get { return _transparentInputWindow.Content; }
set { _transparentInputWindow.Content = value; }
}
private static Window CreateTransparentWindow()
{
var transparentInputWindow = new Window();
//Make the window itself transparent, with no style.
transparentInputWindow.Background = Brushes.Transparent;
transparentInputWindow.AllowsTransparency = true;
transparentInputWindow.WindowStyle = WindowStyle.None;
//Hide from taskbar until it becomes a child
transparentInputWindow.ShowInTaskbar = false;
//HACK: This window and it's child controls should never have focus, as window styling of an invisible window
//will confuse user.
transparentInputWindow.Focusable = false;
return transparentInputWindow;
}
void TransparentInputWindow_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
_parentWindow.Focus();
}
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
base.OnRenderSizeChanged(sizeInfo);
UpdateOverlaySize();
}
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
if (_transparentInputWindow.Visibility != Visibility.Visible)
{
UpdateOverlaySize();
_transparentInputWindow.Show();
_parentWindow = GetParentWindow(this);
_transparentInputWindow.Owner = _parentWindow;
_parentWindow.LocationChanged += ParentWindow_LocationChanged;
_parentWindow.SizeChanged += ParentWindow_SizeChanged;
}
}
private static Window GetParentWindow(DependencyObject o)
{
var parent = VisualTreeHelper.GetParent(o);
if (parent != null)
return GetParentWindow(parent);
var fe = o as FrameworkElement;
if (fe is Window)
return fe as Window;
if (fe != null && fe.Parent != null)
return GetParentWindow(fe.Parent);
throw new ApplicationException("A window parent could not be found for " + o);
}
private void ParentWindow_LocationChanged(object sender, EventArgs e)
{
UpdateOverlaySize();
}
private void ParentWindow_SizeChanged(object sender, SizeChangedEventArgs e)
{
UpdateOverlaySize();
}
private void UpdateOverlaySize()
{
var hostTopLeft = PointToScreen(new Point(0, 0));
_transparentInputWindow.Left = hostTopLeft.X;
_transparentInputWindow.Top = hostTopLeft.Y;
_transparentInputWindow.Width = ActualWidth;
_transparentInputWindow.Height = ActualHeight;
}
}
回答by Tim
If anyone finds themselves unsatisfied with the hacks, setting the Visibility of the WindowsFormsHost to Collapsed or Hidden is always an option.
如果有人发现自己对黑客不满意,将 WindowsFormsHost 的可见性设置为折叠或隐藏始终是一个选项。
回答by Erik
I came across this issue while trying to create a MDI style interface hosting WinForms controls while porting a win forms app to WPF.
我在尝试创建一个托管 WinForms 控件的 MDI 样式界面时遇到了这个问题,同时将一个 win 窗体应用程序移植到 WPF。
I managed to solve it by doing something like this: WindowsFormsHost -> ElementHost -> WindowsFormsHost -> my win forms controls.
我设法通过执行以下操作来解决它:WindowsFormsHost -> ElementHost -> WindowsFormsHost -> 我的 win 表单控件。
Its super ugly, but it creates windows layers for the WPF content to be under the WinForms content.
它超级丑陋,但它为 WPF 内容创建了窗口层,使其位于 WinForms 内容下。