WindowsFormsHost上的工具栏覆盖
我有一个SWF对象嵌入在WPF窗口内的WindowsFormsHost控件中。
我想在swf电影上添加一个工具栏。
我在下面的代码片段的问题是,当新的子节点被添加到主机控件(或者电影被加载,我还没弄明白哪个)时,工具栏实际上是不可见的。 似乎swf的z-index由于某种原因设置为顶部。
这是它的样子:
XAML:
[play, pause, seek columns go here]
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 :( }
任何关于这个问题的见解将不胜感激。
更新:由于没有发布合适的答案,我在下面放置了自己的解决方案。 我意识到这更像是一个黑客而不是解决方案所以我对其他建议持开放态度。
这是我对WindowsFormsHost Z-index问题的解释。
我们的想法是将您需要叠加的任何内容放置在Popup中。 然后,每当调整窗口大小/移动窗口时,根据此答案更新弹出窗口的位置。
注意:您可能还希望在窗口激活/停用时处理事件,因此当窗口失焦(或在另一个窗口后面)时,弹出消失。
XAML:
[same code as before] [toolbar grid goes here]
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(); }
我发现的另一个解决方案是使用Windows Forms的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问题。