WindowsFormsHost上的工具栏覆盖

时间:2012-06-28 15:54:31

标签: c# wpf flash wpf-controls activex

我在WPF窗口内的WindowsFormsHost控件中嵌入了一个SWF对象。

我想在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 :(
}

对此问题的任何见解将不胜感激。


更新:由于没有发布合适的答案,我在下面放置了自己的解决方案。我意识到这更像是一个黑客而不是解决方案所以我对其他建议持开放态度。

2 个答案:

答案 0 :(得分:1)

这是我对WindowsFormsHost Z-index问题的解释。

我们的想法是将您需要叠加的任何内容嵌套在Popup中。然后,每当窗口调整大小/移动时,按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(); }

答案 1 :(得分:0)

我发现的另一个解决方案是使用Windows窗体&#39; 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-indexing问题。