2012-06-28 116 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(); }