web-dev-qa-db-fra.com

Comment faire en sorte qu'une fenêtre WPF soit au-dessus de toutes les autres fenêtres de mon application (pas sur l'ensemble du système)?

Je souhaite que ma fenêtre soit au-dessus de toutes les autres fenêtres dans mon application uniquement . Si je définis la propriété TopMost d'une fenêtre, celle-ci s'ajoute à toutes les fenêtres de toutes les applications et je ne le souhaite pas.

52
Sylvain

Je suis l'OP. Après quelques recherches et tests, la réponse est: 

Non, il n'y a aucun moyen de faire exactement ça.

1
Sylvain

Vous devez définir la propriété propriétaire de la fenêtre.

Vous pouvez afficher une fenêtre via showdialog afin de bloquer votre fenêtre principale, ou vous pouvez l'afficher normalement et l'avoir au sommet du propriétaire sans bloquer le propriétaire.

voici un exemple de code de la partie codeBhind - j'ai laissé de côté tout ce qui est évident:

namespace StackoverflowExample
{
  public partial class MainWindow : Window
  {
    public MainWindow()
    {
      InitializeComponent();
    }
    void NewWindowAsDialog(object sender, RoutedEventArgs e)
    {
      Window myOwnedDialog = new Window();
      myOwnedDialog.Owner = this;
      myOwnedDialog.ShowDialog();
    }
    void NormalNewWindow(object sender, RoutedEventArgs e)
    {
      Window myOwnedWindow = new Window();
      myOwnedWindow.Owner = this;
      myOwnedWindow.Show();
    }
  }
}
33
Johannes

Au lieu de cela, vous pouvez utiliser un Popup toujours TopMost, le décorer de la même manière qu'une fenêtre et le lier complètement avec votre application, gérez l'événement LocationChanged de votre fenêtre principale et définissez la propriété IsOpen de Popup sur false.

Modifier:

J'espère que tu veux quelque chose comme ça:

    Window1 window;

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        window = new Window1();
        window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
        window.Topmost = true;
        this.LocationChanged+=OnLocationchanged;
        window.Show();
    }

    private void OnLocationchanged(object sender, EventArgs e)
    {
          if(window!=null)
              window.Close();
    }

J'espère que ça aide!!!

14
viky
CustomWindow cw = new CustomWindow();

cw.Owner = Application.Current.MainWindow;

cw.ShowInTaskbar = false;

cw.ShowDialog() ; 
11
Alex

La meilleure façon est de définir ces deux événements sur toutes les fenêtres de votre application:

GotKeyboardFocus
LostKeyboardFocus

de cette façon:

WiondowOfMyApp_GotKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
{
    windowThatShouldBeTopMost.TopMost = true;
}

WiondowOfMyApp_LostKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
{
    windowThatShouldBeTopMost.TopMost = false;
}
  • et sûrement que toutes les fenêtres que vous vouliez être en haut devraient être accessibles à partir d’autres fenêtres de votre application . dans mon cas, j’ai une fenêtre de base et une autre fenêtre qui devrait se trouver en haut de la fenêtre de base; pas mal à ma fenêtre de base a instance de chaque autre fenêtre.
5
Omid-RH

utilisez la méthode Activate (). Ceci tente de ramener la fenêtre au premier plan et de l’activer. Fenêtre wnd = new xyz (); Wnd.Activate ();

5
Sudhakar Singh

Je me suis retrouvé dans une situation très similaire à la vôtre. La plupart des recherches que j'ai rencontrées ont indiqué que tout ce que je devais faire était de définir le propriétaire des fenêtres que je souhaitais placer en haut de la fenêtre dans la fenêtre principale ou dans une autre fenêtre appelée Afficher. 

En tout cas, je vais aller de l'avant et poster une solution qui a bien fonctionné pour moi. 

J'ai créé des gestionnaires d'événements pour Window.Activated et Window.Deactived dans la fenêtre qui était supposée être la plus haute en ce qui concerne mon application. 

private void Window_Activated(object sender, EventArgs e)
{
    Topmost = true;
}

private void Window_Deactived(object sender, EventArgs e)
{
    if(Owner == null || Owner.IsActive)
        return;
    bool hasActiveWindow = false;
    foreach(Window ownedWindow in Owner.OwnedWindows)
    {
        if(ownedWindow.IsActive)
            hasActiveWindow = true; 
    }

    if(!hasActiveWindow)
        Topmost = false;
}

Ça marche bien pour moi. J'espère que cela sera utile à quelqu'un d'autre. : o)

4
Ashley Grenon

Dans la fenêtre contextuelle, surcharge la méthode Show () avec un paramètre:

Public Overloads Sub Show(Caller As Window)
    Me.Owner = Caller
    MyBase.Show()
End Sub

Ensuite, dans la fenêtre principale, appelez votre méthode surchargée Show ():

Dim Popup As PopupWindow

Popup = New PopupWindow
Popup.Show(Me)
4
Eric Tremblay

Simple à faire dansXAML, et surpris que personne n'ait encore posté cette réponse. Dans l'exemple suivant, la variable Window est définie dans une variable ResourceLibrary (notez le x:Key), mais vous pouvez également utiliser cette liaison XAML sur une ressource WPF autonome de type Page

<Window x:Key="other_window" 
        Topmost="{Binding Source={x:Static Application.Current},Path=MainWindow.IsActive,Mode=OneWay}">
    <TextBlock Text="OTHER WINDOW" />
</Window>
3
Glenn Slayden

Il y a plusieurs threads, il y a même une balise "topmost". Cherchez sur cela, ou allez directement à ce post qui a l'air bien:

Comment garder une fenêtre au-dessus de toutes les autres fenêtres de mon application uniquement?

2
Chris Thornton

Voici un moyen de le faire: associez votre fenêtre "supérieure" à vos autres événements GotFocus et LostFocus et utilisez les éléments suivants comme gestionnaires d'événements:

class TopMostWindow
{
    void OtherWindow_LostFocus(object sender, EventArgs e)
    {
        this.Topmost = false;
    }

    void OtherWindow_GotFocus(object sender, EventArgs e)
    {
        this.Topmost = true;
    }
}
1
Juan Campa

Vous pouvez ajouter ceci à vos tags Windows

WindowStartupLocation="CenterScreen"

Ensuite, vous pouvez également l'afficher si vous voulez que vos utilisateurs le reconnaissent pour pouvoir continuer. 

YourWindow.ShowDialog();

Essayez d’abord sans paramètres TopMost et voyez les résultats.

0
paradisonoir

Je viens de rencontrer le même problème et j'ai trouvé un problème pour configurer le propriétaire à l'aide de MVVM sans provoquer le blocage de l'application en production. J'ai un modèle d'affichage du gestionnaire de fenêtres qui inclut une commande permettant d'ouvrir une fenêtre à l'aide de l'URI de la fenêtre - et je n'ai pas pu définir le propriétaire sur App.MainWindow sans que l'application ne se bloque.

So - Au lieu de définir le propriétaire, j'ai lié la propriété TopMost de la fenêtre à une propriété de mon modèle Vue du gestionnaire de fenêtres, qui indique si l'application est actuellement active. Si l'application est active, la fenêtre est en haut comme je le voudrais. S'il n'est pas actif, d'autres fenêtres peuvent le couvrir.

Voici ce que j'ai ajouté à mon modèle de vue:

 public class WindowManagerVM : GalaSoft.MvvmLight.ViewModelBase
    {
        public WindowManagerVM()
        {
            App.Current.Activated += (s, e) => IsAppActive = true;
            App.Current.Deactivated += (s, e) => IsAppActive = false;
        }

        private bool _isAppActive = true;
        public bool IsAppActive
        {
            get => _isAppActive;
            set
            {
                if (_isAppActive != value)
                {
                    _isAppActive = value;
                    RaisePropertyChanged(() => IsAppActive);
                }
            }
        }
    }

Voici le XAML qui l'implémente (j'utilise MVVM light avec un ViewModelLocator en tant que ressource statique dans mon application appelée Locator):

<Window Topmost="{Binding WindowManager.IsAppActive, Source={StaticResource Locator}}"/>
0
Chaya Sulman

Moi aussi, j'ai fait face au même problème et suivi Google à cette question. Récemment, j'ai trouvé ce qui suit a fonctionné pour moi.

CustomWindow cw = new CustomWindow();
cw.Owner = this;
cw.ShowDialog();
0
user3104278

Essaye ça:

Popup.PlacementTarget = sender as UIElement;
0
Satya Prakash

Je viens de rencontrer ce même problème. J'ai une application de bureau qui a plusieurs fenêtres WPF et j'avais besoin que mon écran de démarrage personnalisé se trouve au-dessus des autres fenêtres de mon application uniquement. Aucune autre fenêtre n’est ouverte lorsque mon écran de démarrage s’ouvre, mais j’ouvre MainWindow à partir de mon écran de démarrage après une certaine authentification. Donc, je viens de faire quelque chose de similaire à ce que @GlenSlayden a fait, mais en retard de code car, comme je l'ai dit, MainWindow n'est pas à la hauteur de me lier à:

private void SplashScreen_ContentRendered(object sender, EventArgs e)
{
    // User authentication...
    // ...

    MainWindow mainWindow = new MainWindow();
    SetBinding(SplashScreen.TopmostProperty, new Binding("IsVisible"))
    {
        Source = mainWindow,
        Mode = BindingMode.OneWay,
        UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
    };
    mainWindow.Show();
}

Maintenant, pendant que mon programme charge toutes les autres fenêtres depuis MainWindow, l'écran de démarrage est en haut, mais pendant que le programme authentifie l'utilisateur, il n'est pas top, vous pouvez donc cliquer sur un autre programme et le cacher derrière. C'est la chose la plus proche que j'ai pu trouver pour résoudre ce problème. Ce n'est pas parfait, car il continue de surcharger toutes les autres applications pendant le chargement de mon programme après l'authentification, mais ce n'est pas très long dans mon cas.

0
Meloviz

Je viens d'apprendre C # et j'ai rencontré une situation similaire. mais trouvé une solution que je pense peut aider. Vous avez peut-être compris cela il y a longtemps. ce sera à partir d'un nouveau projet mais vous pouvez l'utiliser dans n'importe quel.

1) Commencer un nouveau projet.

2) allez à Projet, puis Nouveau formulaire Windows, puis sélectionnez Formulaire Windows et nommez Splash.

3) définir la taille, l’arrière-plan, le texte, etc. selon les besoins.

4) Sous Propriétés de l'ensemble de formulaires Splash.cs, position de départ: CenterScreen et TopMost: true

5) form1 add "using System.Threading;"

6) form1 dans la classe add "Splash Splashscreen = new Splash ();"

7) form1 add "splashscreen.Show ();" et "Application.DoEvents ();"

8) form1 Sous Events >> Focus >> activé, ajoutez "Thread.Sleep (4000); splashscreen.Close ();"

9) Splash.cs add sous "Public Splash", ajoutez "this.BackColor = Color.Aqua;"/peut utiliser n'importe quelle couleur

10) Ceci est le code pour Form1.cs

public partial class Form1 : Form
{
    Splash splashscreen = new Splash();
    public Form1()
    {
        InitializeComponent();
        splashscreen.Show();
        Application.DoEvents();

    }

    private void Form1_Activated(object sender, EventArgs e)
    {
        Thread.Sleep(4000);
        splashscreen.Close();
    }
}

11) c'est le code sur Splash.cs

public partial class Splash : Form
{
    public Splash()
    {
        InitializeComponent();
        this.BackColor = Color.Aqua;
    }
}

12) J'ai constaté que si vous ne faites PAS quelque chose dans le splash, l'écran ne restera pas en haut pendant le temps que le premier formulaire doit être activé ..__ Le nombre de threads disparaîtra de l'écran après x secondes, votre programme est donc normal.

0
John B

Que dis-tu de ça:

Private Sub ArrangeWindows(Order As Window())
    For I As Integer = 1 To Order.Length -1
        Order(I).Owner = Order(I - 1)
    Next
End Sub
0
Error404