我正在使用一个WPF弹出窗口,但它会在我的桌面上方弹出,即使我的应用程序被最小化。我该如何让它只停留在它所属的窗口上?当我的窗口在其他窗口后面时,同样的事情也会发生:弹出窗口显示在所有窗口的上方。
"一定有办法可以解决的!"
谢谢。
所以,我查看了框架源代码,看看它在哪里导致窗口始终处于最顶层,它是在一个私有嵌套类中实现的。然而,它没有提供选项来仅作为主窗口的子弹出窗口或者成为最顶层窗口。这里有一个技巧可以使它始终成为子弹出窗口。可以轻松地添加依赖属性并进行更多的操作,使其成为最顶层窗口。
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;
};
}
虽然我没有尝试过,但我也读到可以使用装饰器来实现这一点...当被问及同样的问题时,Matt Galbraith在MSDN论坛上建议了这种方法...以防仍有人在阅读此帖。