14

我知道默认的 WPF 行为是呈现 WPF 控件,然后在顶部呈现 WinForms,但是有没有办法在上面呈现 WPF WindowsFormsHost

编辑:我也发现了一个临时黑客。当 wpf 控件重叠WindowsFormsHost时,我更改了的大小WindowsFormsHost(这仅在您有重叠的矩形对象时有效,不适用于其他形状。)

4

6 回答 6

10

我知道聚会迟到了,但我最近使用 WebBrowser 控件遇到了这个问题。

最后的解决方法是每当我在顶部托管一个模态对话框时创建 Web 浏览器的屏幕截图。由于这有点繁琐,我把它变成了一个 Github 项目,希望这会有所帮助 -

https://github.com/chris84948/AirspaceFixer

(它也在 Nuget 上,在 AirspaceFixer 下)

一旦你有了项目,你需要做的就是这个

xmlns:asf="clr-namespace:AirspaceFixer;assembly=AirspaceFixer"

<asf:AirspacePanel FixAirspace="{Binding FixAirspace}">
    <WebBrowser x:Name="Browser" />
</asf:AirspacePanel>

FixAirspace从内容的“真实”视图切换到屏幕截图或“假”视图的依赖属性在哪里。

于 2016-11-23T22:07:17.657 回答
8

这个“空域”问题应该在 WPF vNext中得到修复。有几种解决方案,例如hereherehere

执行此操作的一种方法是将 WPF 内容托管在透明的弹出窗口或窗口中,它覆盖了互操作内容。

于 2011-05-12T13:51:27.870 回答
8

试穿这个尺寸:

<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;
    }
}
于 2014-05-14T18:31:01.380 回答
7

这是迄今为止我在此主题上看到的最佳答案的链接: 我可以将 WPF 窗口覆盖在另一个窗口之上吗?

于 2011-07-09T00:04:30.710 回答
4

如果有人发现自己对这些黑客攻击不满意,则始终可以选择将 WindowsFormsHost 的可见性设置为折叠或隐藏。

于 2016-03-03T21:18:25.840 回答
0

我在尝试创建托管 WinForms 控件的 MDI 样式界面,同时将 win 表单应用程序移植到 WPF 时遇到了这个问题。

我设法通过执行以下操作来解决它:WindowsFormsHost -> ElementHost -> WindowsFormsHost -> my win forms controls。

它超级丑陋,但它为 WPF 内容创建了窗口层,使其位于 WinForms 内容之下。

于 2020-05-04T23:16:08.803 回答