Comment centrer votre fenêtre principale dans WPF?

j'ai une application WPF et j'ai besoin de savoir comment centrer la fenêtre wain programatically (pas dans XAML).

j'ai besoin de pouvoir le faire à la fois au démarrage et en réponse à certains événements utilisateurs. Il doit être calculé dynamiquement puisque la taille de la fenêtre elle-même est dynamique.

Quelle est la façon la plus simple de faire cela? Sous L'ancien code Win32, j'appellerais les fonctions de mesure du système et je m'occuperais de tout. Est-ce que c'est toujours comme ça ou y a-t-il un simple CenterWindowOnScreen() fonction que je peux maintenant appeler.

42
demandé sur paxdiablo 2010-10-26 04:20:58

10 réponses

private void CenterWindowOnScreen()
{
    double screenWidth = System.Windows.SystemParameters.PrimaryScreenWidth;
    double screenHeight = System.Windows.SystemParameters.PrimaryScreenHeight;
    double windowWidth = this.Width;
    double windowHeight = this.Height;
    this.Left = (screenWidth / 2) - (windowWidth / 2);
    this.Top = (screenHeight / 2) - (windowHeight / 2);
}

Vous pouvez utiliser cette méthode pour définir la position de la fenêtre au centre de votre écran.

64
répondu Noppol Pilukruangdet 2016-07-21 14:35:16

bien, pour le temps de démarrage, vous pouvez définir le lieu de démarrage :

window.WindowStartupLocation = WindowStartupLocation.CenterScreen;

plus Tard, vous aurez besoin de l'interroger. Les informations (au moins pour l'écran primaire) sont disponibles via les SystemParameters.PrimaryScreenWidth / Height.

84
répondu Reed Copsey 2010-10-26 00:29:58

n'est-il pas aussi simple de définir

WindowStartupLocation="CenterScreen"

dans la définition XAML pour la fenêtre.

60
répondu naskew 2013-10-01 09:04:41
Rect workArea = System.Windows.SystemParameters.WorkArea;
this.Left = (workArea.Width - this.Width) / 2 + workArea.Left;
this.Top = (workArea.Height - this.Height) / 2 + workArea.Top;

cela prend en compte la taille de la barre des tâches (en utilisant System.Windows.SystemParameters.WorkArea ) et la position (en ajoutant workArea.Left et workArea.Top )

22
répondu Wild_A 2015-09-16 04:30:52

j'ai dû combiner quelques-unes de ces réponses pour couvrir toutes les bases dans mon cas:

  • méthode de Peter pour trouver le moniteur actuel - plutôt que le seul moniteur primaire (sérieusement, qui n'a plus qu'un moniteur au travail?)
  • @ méthode de Wild_A pour utiliser le workarea plutôt que le screen bounds pour tenir compte de l'espace pour la barre des tâches.
  • I a dû ajouter l'échelle DPI, spécifiquement pour une tablette affichant 1280x800 comme 1024x640, mais qui est utile pour couvrir les cas de bord, pour lequel j'ai trouvé une réponse pour ici . Note la variable dpiScaling est nulle si appelée sur la première charge avant que L'UI ne soit affichée ( expliqué ici )
//get the current monitor
Screen currentMonitor = Screen.FromHandle(new System.Windows.Interop.WindowInteropHelper(Application.Current.MainWindow).Handle);

//find out if our app is being scaled by the monitor
PresentationSource source = PresentationSource.FromVisual(Application.Current.MainWindow);
double dpiScaling = (source != null && source.CompositionTarget != null ? source.CompositionTarget.TransformFromDevice.M11 : 1);

//get the available area of the monitor
Rectangle workArea = currentMonitor.WorkingArea;
var workAreaWidth = (int)Math.Floor(workArea.Width*dpiScaling);
var workAreaHeight = (int)Math.Floor(workArea.Height*dpiScaling);

//move to the centre
Application.Current.MainWindow.Left = (((workAreaWidth - (myWindowWidth * dpiScaling)) / 2) + (workArea.Left * dpiScaling));
Application.Current.MainWindow.Top = (((workAreaHeight - (myWindowHeight * dpiScaling)) / 2) + (workArea.Top * dpiScaling));

myWindowWidth et myWindowHeight sont des variables que j'ai utilisées pour régler manuellement la taille de la fenêtre plus tôt.

11
répondu JumpingJezza 2017-05-23 12:26:22

dans l'élément fenêtre il suffit d'ajouter cette paire attribut-valeur: WindowStartupLocation=" CenterScreen "

5
répondu Husam Hilal 2014-03-21 18:07:45

dans le cas où vous avez besoin de dessiner une fenêtre dans un environnement d'écran multiple. J'ai fait une classe statique où la méthode suivante peut être réutilisée:

public static void PostitionWindowOnScreen(Window window, double horizontalShift = 0, double verticalShift = 0)
{
    Screen screen = Screen.FromHandle(new System.Windows.Interop.WindowInteropHelper(window).Handle);
    window.Left = screen.Bounds.X + ((screen.Bounds.Width - window.ActualWidth) / 2) + horizontalShift;
    window.Top = screen.Bounds.Y + ((screen.Bounds.Height - window.ActualHeight) / 2) + verticalShift;        
}

Dans le constructeur de la Fenêtre maintenant, il suffit d'appeler la méthode:

this.Loaded += (s, a) => Globals.PostitionWindowOnScreen(this, 0, 0)
5
répondu Peter 2015-09-16 04:29:19

comme solution de base, vous pouvez utiliser la propriété StartupLocation de window, la mettre à l'une des valeurs enum définies dans le système.Windows.Windowstartuplocation enumeration, il y en a une pour le centre de l'écran:

_wpfWindow.StartupLocation = System.Windows.WindowStartupLocation.CenterScreen;

malheureusement, ce n'est pas toujours aussi simple; vous devez tenir compte de plusieurs moniteurs, barres de tâches, etc. Le "CenterScreen" option ouvre la fenêtre au centre de l'écran qui a le curseur de la souris. Voir cette question pour beaucoup de l'information, de référence ou de la api .

3
répondu Guy Starbuck 2017-05-23 11:54:41

si vous devez être maximisé à la fois

ce.WindowState = Système.Windows.WindowState.Maximized;

0
répondu EpiGen 2015-07-02 05:30:39

basé sur @Wild_A réponse je viens de m'inscrire à l'événement SizeChanged , et j'ai ajouté ce handler d'événement:

private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
    try
    {
        Rect workArea = SystemParameters.WorkArea;
        this.Left = (workArea.Width - e.NewSize.Width) / 2 + workArea.Left;
        this.Top = (workArea.Height - e.NewSize.Height) / 2 + workArea.Top;
    }
    catch (Exception ex) { ... Handel exception; }
}
0
répondu Viking 2016-04-15 12:28:50