2011-05-12 106 views
8

我知道默認的WPF行爲是呈現WPF控件,然後在頂部呈現WinForms,但是有沒有什麼方法可以在WindowsFormsHost之上呈現WPF?在WindowsFormsHost上呈現WPF控件

編輯:我也發現了一個臨時攻擊。當WPF控件重疊WindowsFormsHost,我改變WindowsFormsHost的大小(這僅適用於當你有矩形物體重疊,對於其他形狀不起作用。)

+0

我爲此做的一種方式是覆蓋另一個窗口ontop,透明度和透明度,只要使用全屏的東西就可以很好地工作 – 2015-11-25 15:29:38

回答

5

這個「領空」問題是WPF vNext suppose to be fixed。這裏有幾個解決方案,例如here,herehere

做到這一點的一種方法是將WPF內容託管在覆蓋Interop內容的透明彈出窗口或窗口中。

+5

注意:我對此進行了評論,試圖不讓任何人讀到這個「空域「@ CodeNaked發佈的文章中的問題有一個在.NET 4.5 beta中實現的修復(hwndhost.IsRedirected),但隨後出於任何原因在最終版本中放棄。閱讀[this](http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2644120-bring-back-the-hwndhost-isredirected-and-compositi)和[this](http:/ /social.msdn.microsoft.com/Forums/vstudio/en-US/3a171a12-399c-450b-8ed9-9320e8a6dfce/wpf-45-beta-hwndhostisredirected-and-compositionmode-removed-permanently?forum=wpf) – 2014-04-14 22:59:07

3

試試這個關於大小:

<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; 
    } 
} 
2

如果有人發現自己不滿意的黑客,設置WindowsFormsHost的可見性摺疊或隱藏總是一個選項。

7

我遲到了,我知道,但我最近遇到了這個問題,使用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是從內容的「真實」視圖切換到屏幕截圖或「假」的看法依賴屬性。

相關問題