Come si fa a centrare la tua finestra principale in WPF?

Ho un applicazione WPF e ho bisogno di sapere come centro il wain finestra a livello di codice (non in XAML).

Ho bisogno di essere in grado di fare questo, sia all’avvio e in risposta a determinati eventi utente. Esso deve essere calcolato in modo dinamico dal momento che la dimensione della finestra è dinamico.

Qual è il modo più semplice per fare questo? Sotto il vecchio codice Win32, chiamerei le metriche di sistema funzioni e funziona tutto. È che ancora il modo in cui è fatto o c’è un semplice CenterWindowOnScreen() funzione ora posso chiamare.

InformationsquelleAutor paxdiablo | 2010-10-26



12 Replies
  1. 74
    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);
    }

    È possibile utilizzare questo metodo per impostare la posizione della finestra al centro dello schermo.

    • Te la do io per questo, ma mi sembra di ricordare, è un sacco di lavoro in più, tenendo conto dell’attività di bar e così via. Ancora, +1 per il SystemParameters e un po ‘ di codice così non devo andare a GetSystemMetrics me.
    • Forse l’unico modo per ri-centrare la finestra dopo a livello di programmazione cambiando l’Altezza della finestra e/o Larghezza o dopo il suo percorso è stato modificato.
    • Questo funziona solo se si dispone di 1 monitor, o se tutti i monitor hanno la stessa dimensione
    • Molto utile codice
    • Un po ‘ di proprietà distributiva della divisione, perché la divisione è più costoso, nel senso di prestazioni rispetto a sottrazione:” questo.Sinistra = (screenWidth – larghfinestra)/2;” ecc…
  2. 68

    Non è altrettanto semplice per impostare

    WindowStartupLocation="CenterScreen"

    Nella definizione di XAML per la finestra.

    • Questo va bene per la posizione di avvio, ma, come ho indicato nella domanda, anche io voglio fare questo dal programma quando la finestra si modifica.
    • Mi dispiace, sì, hai ragione. Mi chiedevo perché così tante persone sembrava andare per la mancata soluzione più ovvia. 🙂
  3. 22
    Rect workArea = System.Windows.SystemParameters.WorkArea;
    this.Left = (workArea.Width - this.Width) / 2 + workArea.Left;
    this.Top = (workArea.Height - this.Height) / 2 + workArea.Top;

    Questo prende in considerazione la dimensione della barra delle applicazioni (utilizzando System.Windows.SystemParameters.WorkArea) e la posizione (aggiungendo workArea.Left e workArea.Top)

    • Questo dovrebbe essere accettato risposta.
    • Questo funziona solo se si dispone di 1 monitor, o se tutti i monitor hanno la stessa dimensione
  4. 15

    Ho dovuto combinare un paio di queste risposte per coprire tutte le basi nel mio caso:

    • Pietro metodo per trovare il monitor corrente piuttosto che solo il monitor Principale (serio che ha solo 1 monitor funziona più?)
    • @Wild_A metodo di utilizzare il workarea piuttosto che il screen bounds a prendere in considerazione lo spazio per la barra delle applicazioni.
    • Ho dovuto aggiungere il ridimensionamento DPI, in particolare per i tablet la visualizzazione di 1280×800 come 1024×640, ma che è utile per coprire i casi limite, per il quale ho trovato una risposta per qui. Nota il dpiScaling variabile è nullo se chiamato prima di caricare prima il viene visualizzata l’interfaccia utente (spiegato qui)
    //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));

    dove myWindowWidth e myWindowHeight sono le variabili che ho usato per impostare manualmente la dimensione della finestra precedente.

    • Ho solo un monitor da 40″ con risoluzione 4K. Non può vedere perché qualcuno avrebbe bisogno di più di uno (o che vorresti avere più spazio sulla scrivania). 😉
    • Ah vero! I tempi stanno cambiando 🙂 anche se ancora rilevanti per il collegamento ad un monitor per la demo
    • Grande combinazione di due risposte, appena usato questo e ha funzionato perfettamente. E sì, ho usato 3 schermi, di cui uno con Visual Studio, uno con un pdf(ebook), uno con stackoverflow/outlook
    • Questo dovrebbe definitivamente essere la risposta
  5. 7

    Nel caso In cui avete bisogno di disegnare una finestra in più di schermo ambiente.
    Ho fatto una classe statica in cui il metodo riportato di seguito può essere ri-utilizzato:

    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;        
    }

    Nel costruttore della Finestra ora basta chiamare il metodo:

    this.Loaded += (s, a) => Globals.PostitionWindowOnScreen(this, 0, 0)
    • Per qualche ragione, questo metodo posizioni mia finestra, 20 pixel di distanza dalla parte superiore? Questo funziona meglio per me la risposta scelta.
  6. 5

    Nella finestra elemento è sufficiente aggiungere questa coppia attributo-valore:
    WindowStartupLocation=”CenterScreen”

    • “A livello di programmazione, non in XAML”. In ogni caso, non è un duplicato di naskew risposta?
    • Grazie per questa risposta! Io lavoro in un negozio dove facciamo tutto in xaml. Il “programmatico” è intelligente, ma non è il WPF modo.
    • Così, @James, che è il WPF modo per aumentare il vostro formato delle finestre e di mantenere ancora centrata? L’uso specifico caso ho avuto è stato un 80×24 finestra di terminale per il quale si potrebbe modificare la dimensione del carattere. Al fine di mantenere visibile 80×24 caratteri, le dimensioni della finestra dovuto aumentare, ma volevo tenerlo centrato.
  7. 4

    Come una soluzione di base, è possibile utilizzare la finestra StartupLocation proprietà, impostare uno dei valori enum definito nel Sistema.Windows.WindowStartupLocation enumerazione, c’è un centro di schermo:

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

    Purtroppo non è sempre così semplice; è necessario prendere in considerazione per monitor multipli, le barre delle applicazioni, etc. Il “CenterScreen” opzione consente di aprire la finestra al centro dello schermo con il cursore del mouse. Vedere questa domanda COSÌ per un sacco di informazioni, o di riferimento, il api.

  8. 1

    Quello che sto usando nella mia app, si sta lavorando per più display e per la diversa impostazione DPI

        //center a window on chosen screen
        public static void CenterWindow(Window w, System.Windows.Forms.Screen screen = null)
        {
            if(screen == null)
                screen = System.Windows.Forms.Screen.PrimaryScreen;
    
            int screenW = screen.Bounds.Width;
            int screenH = screen.Bounds.Height;
            int screenTop = screen.Bounds.Top;
            int screenLeft = screen.Bounds.Left;
    
            w.Left = PixelsToPoints((int)(screenLeft + (screenW - PointsToPixels(w.Width, "X")) / 2), "X");
            w.Top = PixelsToPoints((int)(screenTop + (screenH - PointsToPixels(w.Height, "Y")) / 2), "Y");
        }
    
        public static double PixelsToPoints(int pixels, string direction)
        {
            if (direction == "X")
            {
                return pixels * SystemParameters.WorkArea.Width / System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width;
            }
            else
            {
                return pixels * SystemParameters.WorkArea.Height / System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height;
            }
        }
    
        public static double PointsToPixels(double wpfPoints, string direction)
        {
            if (direction == "X")
            {
                return wpfPoints * System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width / SystemParameters.WorkArea.Width;
            }
            else
            {
                return wpfPoints * System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height / SystemParameters.WorkArea.Height;
            }
        }
  9. 0

    Basato su @Wild_A risposta che ho appena sottoscritto la SizeChanged evento, e ha aggiunto di questo gestore di eventi:

    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; }
    }
  10. 0

    Andare alla finestra di proprietà di MainWindow.xaml

    • trovare WindowStartupLocation proprietà dal Comune categoria
    • selezionare CenterScreen opzione dal menu a discesa
    • Eseguire l’Applicazione

    A Schermo Intero

    Andare alla finestra di proprietà di MainWindow.xaml

    • trovare WindowState proprietà dal Comune categoria
    • selezionare Ingrandita opzione dal menu a discesa
    • Eseguire l’Applicazione
  11. -1

    Se si è di essere ottimizzata per una volta

    questo.WindowState = System.Windows.WindowState.Ingrandita;

Lascia un commento