C# WPF弹出式ZOrder
我使用的是WPF弹出窗口,但它会在我桌面上的每个窗口上弹出,即使我的应用程序最小化了。我怎样才能让它只停留在窗户上?当我的窗口位于其他窗口之后时,也会发生同样的情况:弹出窗口显示在所有窗口的上方 “一定有办法!”C# WPF弹出式ZOrder,c#,wpf,xaml,z-order,C#,Wpf,Xaml,Z Order,我使用的是WPF弹出窗口,但它会在我桌面上的每个窗口上弹出,即使我的应用程序最小化了。我怎样才能让它只停留在窗户上?当我的窗口位于其他窗口之后时,也会发生同样的情况:弹出窗口显示在所有窗口的上方 “一定有办法!” 谢谢。我也试图解决这个问题,但没有找到好的解决方案。这似乎是它的工作方式,你不能忽略它 我提出的唯一解决方案是只使用常规布局面板并提高其Z索引,因此它是顶级控件(这类控件模拟弹出窗口)。我唯一一次发现这不起作用是当你通过WindowsFormsShosts在屏幕上显示WinForms时
谢谢。我也试图解决这个问题,但没有找到好的解决方案。这似乎是它的工作方式,你不能忽略它 我提出的唯一解决方案是只使用常规布局面板并提高其Z索引,因此它是顶级控件(这类控件模拟弹出窗口)。我唯一一次发现这不起作用是当你通过WindowsFormsShosts在屏幕上显示WinForms时。这些Winforms的Z索引总是比任何WPF的东西都高。此时,您必须使用弹出窗口来绕过它。请检查:
也许这能帮到你 虽然我没有试过这么做,我还读到,这可以通过使用装饰器来实现……马特·加尔布雷斯在MSDN论坛上提出了同样的问题……以防有人还在读这篇文章。因此,我深入研究了框架源代码,以了解它实际导致窗口位于最顶端的位置,并在私有嵌套类中实现了这一点。但是,它不提供一个选项,既可以是主窗口的子弹出窗口,也可以是最上面的窗口。这里有一个黑客使它始终是一个儿童弹出窗口。你可以很容易地添加一个依赖属性,并做一些更神奇的事情使它成为最顶级的属性
using System;
using System.Reflection;
using System.Windows;
using System.Windows.Controls.Primitives;
namespace UI.Extensions.Wpf.Controls
{
public class ChildPopup : Popup
{
static ChildPopup()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ChildPopup), new FrameworkPropertyMetadata(typeof(ChildPopup)));
}
public ChildPopup()
{
Type baseType = this.GetType().BaseType;
dynamic popupSecHelper = GetHiddenField(this, baseType, "_secHelper");
SetHiddenField(popupSecHelper, "_isChildPopupInitialized", true);
SetHiddenField(popupSecHelper, "_isChildPopup", true);
}
protected dynamic GetHiddenField(object container, string fieldName)
{
return GetHiddenField(container, container.GetType(), fieldName);
}
protected dynamic GetHiddenField(object container, Type containerType, string fieldName)
{
dynamic retVal = null;
FieldInfo fieldInfo = containerType.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldInfo != null)
{
retVal = fieldInfo.GetValue(container);
}
return retVal;
}
protected void SetHiddenField(object container, string fieldName, object value)
{
SetHiddenField(container, container.GetType(), fieldName, value);
}
protected void SetHiddenField(object container, Type containerType, string fieldName, object value)
{
FieldInfo fieldInfo = containerType.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldInfo != null)
{
fieldInfo.SetValue(container, value);
}
}
}
}
我就是这样解决的:
private void Popup_Opened(object sender, EventArgs events)
{
Popup popup = (Popup)sender;
// Get window to make popop follow it when user change window's location.
Window w = Window.GetWindow(popup);
// Popups are always on top, so when another window gets focus, we
// need to close all popups.
w.Deactivated += delegate (object s, EventArgs e)
{
popup.IsOpen = false;
};
// When our dialog gets focus again, we show it back.
w.Activated += delegate (object s, EventArgs e)
{
popup.IsOpen = true;
};
}
如果你像我一样需要从ChildPopup继承,代码将无法正常工作。我将popuspechelper行更改为:object popuspechelper=GetHiddenField(this,typeof(Popup),“\u secHelper”);另外,我跳过了DefaultStyleKeyProperty覆盖,因为它似乎不需要,我也不明白为什么应该这样做。我有同样的问题,无法解决它。很难相信这是默认行为,但MSDN在这方面毫无用处。我解决这个问题的方法是在windowxaml中将包含comboBox的整个窗口设置为TopMost=True。这使得整个窗口位于顶部,而不仅仅是“我的组合框”(与弹出窗口中的情况相同)的下拉列表。在提示警报时,主窗口不会停用,提示消息显示在后面