如何在C#中引用WPF应用程序的活动窗口,使用类似WinForms中的ActiveForm属性的方法?
一种可能的方法是扫描应用程序中打开窗口的列表,并检查哪一个窗口具有 IsActive = true
:
Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);
不确定是否可能存在多个活动窗口,例如如果有一个模态对话框正在显示,则对话框的所有者和对话框本身可能是活动的。
使用PInvoke有更好的方法来解决这个问题。Aviad的答案并不总是有效(在某些边缘情况下存在一些对话框)。
IntPtr active = GetActiveWindow();
ActiveWindow = Application.Current.Windows.OfType<Window>()
.SingleOrDefault(window => new WindowInteropHelper(window).Handle == active);
首先必须包含以下导入:
[DllImport("user32.dll")]
static extern IntPtr GetActiveWindow();
IsActive
。使用另一种解决方案会抛出异常(如果有多个匹配谓词,则 SingleOrDefault
会抛出异常),或者在使用 FirstOrDefault
时没有给我实际的活动窗口。 - clcto我知道这个问题有些老,但是我认为我的答案可以帮助到某些人。
我的问题是:我有一个WPF MVVM应用程序,我需要在第二个视图模型中获取我的MainWindow
实例,以便将标题栏按钮的可见性设置为visible
。
这是我的解决方案:
MainWindow window = (MyApp.MainWindow)App.Current.MainWindow;
window.btnSearch.Visibility = System.Windows.Visibility.Visible;
希望这能对某些人有所帮助。
另一种方法是使用user32.dll中的本地GetActiveWindow
函数。
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetActiveWindow();
要将其转换为实际的 WPF 窗口:
IntPtr handle = GetActiveWindow();
HwndSource hwndSource = HwndSource.FromHwnd(handle);
var window = hwndSource?.RootVisual as Window;
WindowInteropHelper
。这样可以使窗口所有者正常工作,例如:var wih = new WindowInteropHelper(window)
{
Owner = GetActiveWindow()
};
我编辑了我的旧答案,因为在 Visual Studio 更新后我遇到的边缘情况已经消失了,但是可以从答案历史记录中检查。在那里我遇到了一个问题,在调试时在某些情况下获取活动窗口时会得到 null。
我遇到了一个关于编程的问题,具体是这样的:"Application.Current.Windows.OfType().SingleOrDefault(x => x.IsActive);",特别是当我正在建立一个带有主窗口的应用程序时,当主窗口被选中时会出现问题。为了解决这个问题,我创建了以下代码:
在基类或App.xaml.cs文件中创建以下代码:
public static Window ActivatedWindow {get;set;}
然后在您的基类中加入继承自 Window 或所有 Window 的 Activate 事件:
第一选项 - 个人窗口基类:
public class MetroToolWindowBase
{
public MetroToolWindowBase()
{
Activated += new EventHandler(MakeActive);
}
private void MakeActive(object sender, EventArgs e)
{
App.ActivatedWindow= this;
}
}
第二个选项- 在 Windows 的激活事件中:
private void XWindow_Activated(object sender,EventArgs e)
{
App.ActivatedWindow= this;
}
OfType<Window>()
运算符而不是Cast<Window>()
,以防万一... - Aviad P.FirstOrDefault
替代SingleOrDefault
,如果有多个匹配项,后者会抛出异常。此外,FirstOrDefault
速度稍微快一些,因为它只接受第一个结果,不需要检查它是否是唯一的。 - ygoeFirstOrDefault
和SingleOrDefault
都会返回null
,这意味着没有IsActive
为 true 的窗口。这是怎么可能的? - digitguy