pkain
pkain

Reputation: 687

Refer to active Window in WPF?

How can I refer to active Window of WPF application in C#, using something like ActiveForm property in WinForms?

Upvotes: 66

Views: 66171

Answers (5)

Shahin Dohan
Shahin Dohan

Reputation: 6907

Another way to do it is to use the native GetActiveWindow function from user32.dll.

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetActiveWindow();

To convert it to an actual WPF Window:

IntPtr handle = GetActiveWindow();

HwndSource hwndSource = HwndSource.FromHwnd(handle);
var window = hwndSource?.RootVisual as Window;

If hosting a WPF Window in a WinForms app, WindowInteropHelper should be used. This makes for example the Window owner work correctly:

var wih = new WindowInteropHelper(window)
{
    Owner = GetActiveWindow()
};

I edited my old answer because the edge case I encountered disappeared after a Visual Studio update, but it can be checked from answer history. I encountered an issue there where I was getting null for active window in certain circumstances while debugging.

Upvotes: 0

NutCracker
NutCracker

Reputation: 12253

I know this is a bit old question but I think my answer could help someone.

My problem was this: I had a WPF MVVM application and I needed to get my MainWindow instance in the second view, i.e. second view model, in order to set the visibility of title bar button to visible.

This is my solution:

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

Hope this would help someone.

Upvotes: 2

Richard Aguirre
Richard Aguirre

Reputation: 634

I have problems With this way "Application.Current.Windows.OfType().SingleOrDefault(x => x.IsActive);" specialy because I was building an aplication with a main Window then i had problems when the main window was selected. I resolve it creating this:

In some base class or App.xaml.cs create this:

       public static Window ActivatedWindow {get;set;}

Then put in your base class deriving Window or all of your Window's Activate Event:

First Option - personal Window Base Class:

       public class MetroToolWindowBase
       {
         public MetroToolWindowBase()
         {   
            Activated += new EventHandler(MakeActive); 
         }   
         private void MakeActive(object sender, EventArgs e)
         {
        App.ActivatedWindow= this;
         }
       }

Second Option- In Activated Event of Windows:

   private void XWindow_Activated(object sender,EventArgs e)
    {
     App.ActivatedWindow= this;
    }

Upvotes: 0

ghord
ghord

Reputation: 13797

There is better way to do this using PInvoke. Aviads answer is not working all the time (there are some edge cases with dialogs).

IntPtr active = GetActiveWindow();

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

One must include following import first:

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

Upvotes: 30

Aviad P.
Aviad P.

Reputation: 32629

One possible way would be to scan the list of open windows in the application and check which one of them has IsActive = true:

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

Not sure if there may be more than one active window if, for example, there's a modal dialog showing, in which case, the owner of the dialog and the dialog itself might be active.

Upvotes: 119

Related Questions