web-dev-qa-db-fra.com

WPF toujours au top

Est-il possible de faire en sorte qu'une fenêtre reste toujours au premier plan même si une autre application s'exécute en mode plein écran? J'utilise en ce moment TopMost = true mais quand une autre application tourne en plein écran, le mien devient invisible. C'est WindowStyle = None fenêtre au fait.

Edit: Et ne laissez pas une autre fenêtre minimiser bien sûr

44
Kuba Wasilczyk

Cela ne fonctionnera pas à 100% du temps, mais cela améliorera quelque peu la situation. Vous pouvez définir Topmost = true dans le gestionnaire pour le Window.Deactivated événement:

private void Window_Deactivated(object sender, EventArgs e)
{
    Window window = (Window)sender;
    window.Topmost = true;
}

L'événement Deactivated sera appelé chaque fois que votre application perd son focus (souvent lorsqu'une autre application demande à être Topmost), ce qui réinitialisera votre application par la suite.

43
Sheridan

Essayez cette solution à partir de MSDN, cela devrait fonctionner pour vous. Dans le Window Activated Event ajoutez le code suivant:

this.Width = System.Windows.SystemParameters.PrimaryScreenWidth;
this.Height = System.Windows.SystemParameters.PrimaryScreenHeight;
this.Topmost = true;
this.Top = 0;
this.Left=0;

dans DeActivated Event ajouter le code suivant

this.Topmost = true;
this.Activate();

Post original de MSDN

12
Mohammed A. Fadil

Aucune des solutions ci-dessus n'a fonctionné pour moi, alors voici ce que j'ai fini par faire. Cela a fonctionné parfaitement pour moi.

En gros, pour rester au top, il suffit de définir l’événement de perte de focus pour le ramener au sommet.

XAML:

PreviewLostKeyboardFocus="Window_PreviewLostKeyboardFocus"

Code Derrière:

private void Window_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
     {
          Window window = (Window)sender;
          window.Topmost = true;
     }
5
Travis Tubbs

Si vous souhaitez que votre application reste au-dessus de TOUT (y compris l'interface de démarrage de Windows 8, connue auparavant sous le nom de "Metro"), vous pouvez spécifier UiAccess = "True" dans votre fichier manifeste. Ceci est généralement utilisé par les applications d'accessibilité telles que les claviers à l'écran.

De mémoire, vous devez faire 3 choses;

  1. Demander UiAccess = "True"
  2. Signez le fichier exe de votre application avec un certificat reconnu. J'ai obtenu un certificat de signature de code gratuit de Certum car mon projet est Open Source.
  3. Installez votre application dans un "emplacement de confiance", qui dans mon cas était le répertoire des fichiers du programme. Il n'y a pas de définition officielle de "Emplacement de confiance" que j'ai pu trouver.
2
Julius

J'ai donc rencontré la même exigence récemment. Il semble que la réponse la mieux notée ainsi que la seconde ne fonctionnent pas correctement pour moi. J'ai trouvé une solution qui semble fonctionner parfaitement et qui respecte quelque peu les meilleures pratiques en utilisant MVVM.

L'utilisation de l'option ci-dessous force la fenêtre vers le haut et n'interrompt jamais le changement, à l'instar des autres solutions.

Étape 1: J'ai créé une classe de gestionnaire d'état simple pour la fenêtre de mon client principal. J'ai utilisé INotifyPropertyChanged pour garder la propriété synchronisée lors de l'utilisation d'une liaison directe à ma fenêtre. (très important)

public class ClientStateManager : INotifyPropertyChanged
{
    #region Private Variables
    private bool isForceToTop;
    private bool isClientEnabled;
    #endregion

    #region Public Properties
    public bool IsForceToTop
    {
        get { return isForceToTop; }
        set
        {
            isForceToTop = value;
            NotifyPropertyChanged();
        }
    }
    public bool IsClientEnabled
    {
        get { return isClientEnabled; }
        set
        {
            isClientEnabled = value;
            NotifyPropertyChanged();
        }
    }       
    #endregion

    #region Private Methods
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion

    #region Public Methods
    public void Lock() => this.IsClientEnabled = false;
    public void UnLock() => this.IsClientEnabled = true;
    public void SetTop() => this.IsForceToTop = true;
    public void UnSetTop() => this.IsForceToTop = false;
    #endregion

    #region Public Events
    public event PropertyChangedEventHandler PropertyChanged; 
    #endregion
}

Étape 2.1: Ajout de ma classe de gestionnaire d’état à ViewModel. (MVVM)

  internal class MainWindowViewModel : INotifyPropertyChanged
  {
    #region Constructor
    public MainWindowViewModel() 
    {
        ClientStateManager = new ClientStateManager();
    }
    #endregion

    #region Public Properties  
    public ClientStateManager ClientStateManager { get; private set; }
    #endregion
  }

Étape 2.2: Définissez ensuite le contexte de vos données de fenêtre sur votre modèle de vue.

  private MainWindowViewModel model;
  private MainWindow()
  {
        InitializeComponent();
        this.model = new MainWindowViewModel();
        this.DataContext = model;
  }   

Étape 3: Ajoutez votre liaison de données à votre fenêtre.

  <Window x:Class="Intouch_Work.MainWindow"
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.Microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:ojects="clr-namespace:Framework.Object;Assembly=Framework"
    xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"     
    mc:Ignorable="d"
    Title="Intouch" Height="800" Width="1100"
    x:Name="mainWindow"
    Topmost="{Binding Path=ClientStateManager.IsForceToTop, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">

Vous pouvez donc maintenant gérer votre état de fenêtre à l'aide de l'objet Gestionnaire d'état initialisé dans le modèle de vue. Vous pouvez appeler SetTop () depuis votre gestionnaire d’état pour le faire avancer ou unSetTop () pour l’arrêter. J'espère que cela aidera tous ceux qui cherchent à faire de même.

2
B.Spangenberg

J'avais une fenêtre principale que je voulais garder au-dessus de tout (si l'utilisateur coche "toujours au top").
Cela a fonctionné pour moi. J'espère que ça aide quelqu'un.

        // If we want main to stay on top, we set the rest of the menus to Not be top 
        if (mnuViewMainWindowAlwaysOnTopo.IsChecked)
        {
            this.Topmost = true;
            foreach (Window window in Application.Current.Windows)
            {
                // Don't change for main window
                if (window.GetType().Name != this.GetType().Name)
                {
                    window.Topmost = false;
                }
            }
        }
        else
        {
            this.Topmost = false;
        }
1
pStan