3

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

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


更新:由于没有发布合适的答案,我在下面放置了自己的解决方案。我意识到这更像是一种技巧,而不是一种解决方案,所以我愿意接受其他建议。

4

2 回答 2

1

这是我解决 WindowsFormsHost Z-index 问题的方法。

这个想法是将您需要覆盖的任何内容嵌套在弹出窗口中。然后在调整窗口大小/移动窗口时根据此答案更新该弹出窗口的位置。

注意:您可能还希望在窗口被激活/停用时处理事件,因此当窗口失去焦点(或在另一个窗口后面)时弹出消失。

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(); }
于 2012-07-05T16:06:29.840 回答
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 中编写我的 UserControl,但现在我不必担心 Z 索引问题。

于 2012-07-24T15:56:10.253 回答