Developing for Modern Windows

Tips, tricks, and guides for developing on modern Windows platforms

Detect when a UWP App Loses or Gains Focus or Visibility

If you want your Universal Windows Platform (UWP) app to do something special when the app loses or gains focus (such as pausing and resuming video playback), you’ll need to detect changes in app focus.

You may similarly want to take action when the app becomes invisible (e.g. minimised) or visible.

You can subscribe to two events that notify your app of these changes:

  • Window.Current.Activated notifies of focus changes, and
  • Window.Current.VisibilityChanged notifies of visibility changes.

focus

How it Works

The app’s focus can have three values:

  • Deactivated (no focus)
  • PointerActivated (activated by the user clicking within the window)
  • CodeActivated (activated by the Activated event, usually by the OS giving the app focus, e.g. when the app is launched).

The app’s visibility can have two values:

  • True (visible)
  • False (not visible).
Visibility doesn’t take into account your app being behind other apps and not visible, it only detects if your app is on the screen. The focus state will change to Deactivated when your app is behind another app.

An Example

This example app will be very simple, you’ll just have three TextBlocks that display the focus state and how many times the app becomes visible or invisible.

Start a blank UWP project and replace the default Grid with the following XAML in MainPage.xaml:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
   <StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
     <TextBlock x:Name="FocusStatus" Text="Nothing to report" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="36"/>
     <TextBlock x:Name="InvisibleCount" Text="Visible count: 0" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="36"></TextBlock>
     <TextBlock x:Name="VisibleCount" Text="Invisible count: 0" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="36"></TextBlock>
   </StackPanel>
 </Grid>

There is nothing special in that code, it’s just three TextBlocks stacked, but it’s enough UI to demonstrate this functionality.

Add the Code

Now for the code that does the work.

Subscribe to the Events

Add the following event handlers to the MainPage() method in MainPage.xaml.cs to subscribe to the focus and visibility notifications:

Window.Current.Activated += Current_Activated;
Window.Current.VisibilityChanged += Visibility_Changed;

Add the Event Handler Code

You’ll two event handers, one for the focus change and one for the visibility change.

Visibility Event Handler

private void Visibility_Changed(object sender, VisibilityChangedEventArgs e)
 {
     if (e.Visible)
     {
         visibleCount ++;
         VisibleCount.Text = "Visible count: " + visibleCount.ToString();
     }
     else
     {
         invisibleCount ++;
         InvisibleCount.Text = "Invisible count: " + invisibleCount.ToString();
     }
 }

Focus Event Handler


void Current_Activated(object sender, Windows.UI.Core.WindowActivatedEventArgs e)
{
    if (e.WindowActivationState ==
        Windows.UI.Core.CoreWindowActivationState.Deactivated)
    {
        FocusStatus.Text = "Focus lost!";

    }
    else if (e.WindowActivationState ==
        Windows.UI.Core.CoreWindowActivationState.PointerActivated)
    {
        FocusStatus.Text = "App has focus from clicking";
    }
    else if (e.WindowActivationState == Windows.UI.Core.CoreWindowActivationState.CodeActivated)
    {
        FocusStatus.Text = "App has focus from the OS";
    }
}

Test the App

Run the app and experiment with giving the app focus, and minimise and maximise the app.

The focus text changes based on whether the app has focus, and if it has focus, how the focus was given. The visible/invisible counts will increase when the app is minimised and maximised.

You can use this event handler as the basis for any kind of focus-based functionality. Try adding a simple media player to the project, and pause or resume playback based on the different states.

Remember to unsubscribe to the event handler in the user navigates away from the page or you might get some strange behavior.

Tags: , ,

Leave a Reply

Your email address will not be published.