2010-01-10 105 views

回答

81

一種可能的方式是掃描應用程序中打開的窗口的列表,並檢查它們中一個具有IsActive = true

Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive); 

不知道是否有可能不止一個活動窗口,如果,例如,會出現一個模式對話框,在這種情況下,對話框的所有者和對話框本身可能處於活動狀態。

+0

再看看我的舊答案,使用'OfType ()'操作符而不是'Cast ()'可能更好 - – 2012-06-20 08:00:53

+0

真棒!這使我不必傳遞一個引用到窗口,這使我的數據結構免於UI引用。謝謝! – BrokeMyLegBiking 2013-03-07 22:19:46

+5

爲了使它更健壯,你可以使用'FirstOrDefault'而不是'SingleOrDefault',如果有多個匹配的項目會引發異常。另外它應該快一點,因爲它接受第一個結果,並且不需要檢查它是唯一的結果。 – ygoe 2013-10-25 15:04:01

19

有更好的方法來使用PInvoke來做到這一點。答案答案不是一直在工作(有一些邊界案例與對話框)。

IntPtr active = GetActiveWindow(); 

ActiveWindow = Application.Current.Windows.OfType<Window>() 
    .SingleOrDefault(window => new WindowInteropHelper(window).Handle == active); 

一個必須包括以下導入第一:

[DllImport("user32.dll")] 
static extern IntPtr GetActiveWindow(); 
+1

呵呵。我花了幾個小時才發現這一點。我實際上寫了與你完全相同的東西並來這裏分享,但你是第一個,所以這是我的投票:P – 2013-01-15 15:04:53

+6

你能否詳細說明邊緣案例? – nchaud 2013-04-24 15:06:01

+1

@nchaud我使用AvalonDock,它允許您將工作區拖出主窗口並進入新窗口。但是,這些窗口也被標記爲「IsActive」。使用其他解決方案拋出一個異常(如果有多個匹配的謂詞,則拋出SingleOrDefault),或者在使用'FirstOrDefault'時沒有給我實際的活動窗口 – clcto 2014-08-07 21:06:16

0

我有問題有了這種方式 「Application.Current.Windows.OfType()的SingleOrDefault(X => x.IsActive);」因爲我正在用主窗口構建應用程序,所以在選擇主窗口時遇到了問題。我解決這個問題創造這樣的:

在一些基礎類或App.xaml.cs創建此:

 public static Window ActivatedWindow {get;set;} 

然後把你的基類派生窗口或全部窗口的激活事件:

第一個選項 - 個人窗口的基類:

 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; 
    } 
0

我知道這是一個有點老的問題,但我認爲我的答案可以幫助某人。

我的問題是這樣的:我有一個WPF MVVM應用程序,我需要在第二個視圖(即第二個視圖模型)中獲得我的MainWindow實例,以便將標題欄按鈕的可見性設置爲visible

這是我的解決方案:

MainWindow window = (MyApp.MainWindow)App.Current.MainWindow; 
window.btnSearch.Visibility = System.Windows.Visibility.Visible; 

希望這會幫助別人。