Setting a WPF Window to be Always on Top

January 5, 2013

tags: , , ,
no comments

Some applications require that their main window will always be on top of all the other windows. Doing so in WPF is quite simple. In this post I will show how.

In order for the window to be opened on top of all the other windows, set its Topmost property to True. Doing just that is not enough, because when the window will lose its focus, it will be placed behind the focused window. To keep the window top-most even after it loses its focus, add an EventTrigger to the window’s LostFocus event, and set the Topmost property to be True again:

   1: <Window x:Class="AlwaysOnTopDemo.MainWindow"

   2:         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   3:         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   4:         Title="MainWindow" Height="350" Width="525"

   5:         Topmost="True">

   6:     <Window.Triggers>

   7:         <EventTrigger RoutedEvent="LostFocus">

   8:             <BeginStoryboard>

   9:                 <Storyboard>

  10:                     <BooleanAnimationUsingKeyFrames>

  11:                         <DiscreteBooleanKeyFrame KeyTime="0" 

  12:                                                  Value="True" 

  13:                                                  Storyboard.Target="{Binding RelativeSource={RelativeSource AncestorType=Window}}" 

  14:                                                  Storyboard.TargetProperty="Topmost"/>

  15:                     </BooleanAnimationUsingKeyFrames>

  16:                 </Storyboard>

  17:             </BeginStoryboard>

  18:         </EventTrigger>

  19:     </Window.Triggers>

  20:     

  21:     <Grid> 

  22:     </Grid>

  23: </Window>

Using the same EventTrigger over and over again can be tiring and erroneous. We can save a lot a keystrokes and make the above code reusable by creating a behavior:

   1: using System.Windows;

   2: using System.Windows.Interactivity;

   3:  

   4: namespace WPFUtils.Behaviors

   5: {

   6:     public class AlwaysOnTopBehavior : Behavior<Window>

   7:     {

   8:         protected override void OnAttached()

   9:         {

  10:             base.OnAttached();

  11:             AssociatedObject.LostFocus += (s, e) => AssociatedObject.Topmost = true;

  12:         }

  13:     }

  14: }

And the usage:

   1: <Window x:Class="WPFUtils.Samples.AlwaysOnTopBehavior.MainWindow"

   2:         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   3:         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   4:         xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

   5:         xmlns:behaviors="clr-namespace:WPFUtils.Behaviors;assembly=WPFUtils" 

   6:         Topmost="True"

   7:         Title="AlwaysOnTopBehavior Sample" Height="350" Width="525">

   8:     

   9:     <i:Interaction.Behaviors>

  10:         <behaviors:AlwaysOnTopBehavior/>

  11:     </i:Interaction.Behaviors>

  12:     <Grid>

  13:     </Grid>

  14: </Window>

Keep in mind that using this technique on more than one window will not work, because all the windows will try to set themselves to be top-most, and the one with the focus will win.

The AlwaysOnTopBehavior class is available on GitHub, as part of my WPFUtils project.

Cross-posted from http://www.programmingtidbits.com/post/2013/01/05/Setting-WPF-Window-to-be-Always-on-Top.aspx

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*