2012-06-28 165 views
3

我有一個嵌入WPF窗口內的WindowsFormsHost控件的SWF對象。工具欄覆蓋在WindowsFormsHost

我想在swf電影上添加一個工具欄。

下面的代碼片段的問題是,當新的孩子被添加到主機控件(或電影加載,我還沒有想出哪些),工具欄是有效地不可見。看起來swf的z-index是由於某種原因設置爲最高的。

這裏是什麼樣子:

XAML:

<Grid Name="Player"> 
    <WindowsFormsHost Name="host" Panel.ZIndex="0" /> 
    <Grid Name="toolbar" Panel.ZIndex="1" Height="50" 
     VerticalAlignment="Bottom"> 
      [play, pause, seek columns go here] 
    </Grid> 
</Grid> 

C#:

private void Window_Loaded(object sender, RoutedEventArgs e) 
{ 
    flash = new AxShockwaveFlashObjects.AxShockwaveFlash(); 
    host.Child = flash; 
    flash.LoadMovie(0, [movie]); // Movie plays, but no toolbar :(
} 

在這個問題上任何有識之士將不勝感激。


更新:由於沒有合適的答案貼出來,我下面放置自己的解決方案。我意識到這比解決方案更像是一種攻擊,所以我願意接受其他建議。

+0

注:我也嘗試在彈出框中嵌套'工具欄',以'主機'爲目標。這種方法的問題是,如果窗口被移動/調整大小,彈出窗口不會跟隨。 – funseiki

+0

看起來,這可能是不可能的,沒有一些黑客。微軟的[post](http://msdn.microsoft.com/en-us/library/ms744952.aspx) – funseiki

+0

(來自你上面的鏈接)「託管的Windows Forms控件也繪製在任何Adorner元素之上。」我打算說使用Adorner,但看起來這也不起作用。 – Tom

回答

0

我發現另一種解決方案是使用Windows窗體ElementHost控件。由於我在WPF窗口中使用Windows窗體,爲什麼不使用整個Windows窗體並保存自己的Z-Issue問題。

ElementHost控件真的很有用,因爲我仍然可以使用我的工具欄UserControl,並將它嵌入到Windows窗體中。我發現添加一個孩子可以用Windows窗體挑剔,所以這裏有一個描述解決方案的片段:

首先,使用設計器折騰ActiveX對象,然後是ElementHost控件。

Form1.Designer.cs:

private AxShockwaveFlashObjects.AxShockwaveFlash flash; 
private System.Windows.Forms.Integration.ElementHost elementHost1; 

Form1.cs的

public Form1(string source) 
{ 
    InitializeComponent(); 
    toolbar = new UserControl1(); 
    this.elementHost1.Child = this.toolbar; 
    this.flash.LoadMovie(0, source); 
} 

注意的是,孩子沒有在設計器中設置。我發現對於更復雜的UserControl,設計者會抱怨(儘管在運行時沒有任何反應)。

該解決方案當然還不完全理想,但它提供了兩全其美的方法:我仍然可以在XAML中編寫UserControls,但現在我不必擔心Z索引問題。

0

這是我的hackaround WindowsFormsHost Z索引問題。

這個想法是放置任何你需要疊加在一個彈出窗口中的嵌套。然後根據this answer更新彈出窗口的位置,只要窗口被調整大小/移動。

注意:當窗口變爲激活/取消激活時,您可能還需要處理事件,因此當窗口不在焦點(或在另一個窗口後面)時彈出消失。

XAML:

<Window [stuff] 
    LocationChanged="Window_LocationChanged" 
    SizeChanged="Window_SizeChanged" > 
    <Grid Name="Player"> 
    [same code as before] 
     <Popup Name="toolbar_popup" IsOpen="True" PlacementTarget="{Binding ElementName=host}"> 
      [toolbar grid goes here] 
     </Popup> 
    </Grid> 
</Window> 

C#:

private void resetPopup() 
{ 
    // Update position 
    // https://stackoverflow.com/a/2466030/865883 
    var offset = toolbar_popup.HorizontalOffset; 
    toolbar_popup.HorizontalOffset = offset + 1; 
    toolbar_popup.HorizontalOffset = offset; 

    // Resizing 
    toolbar_popup.Width = Player.ActualWidth; 
    toolbar_popup.PlacementRectangle = new Rect(0, host.ActualHeight, 0, 0); 
    toolbar_popup.Placement = System.Windows.Controls.Primitives.PlacementMode.Top; 
} 
private void Window_LocationChanged(object sender, EventArgs e) 
{ resetPopup(); } 

private void Window_SizeChanged(object sender, SizeChangedEventArgs e) 
{ resetPopup(); }