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.
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.
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.
n'est-il pas aussi simple de définir
WindowStartupLocation="CenterScreen"
dans la définition XAML pour la fenêtre.
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
)
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 lescreen 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));
où myWindowWidth
et myWindowHeight
sont des variables que j'ai utilisées pour régler manuellement la taille de la fenêtre plus tôt.
dans l'élément fenêtre il suffit d'ajouter cette paire attribut-valeur: WindowStartupLocation=" CenterScreen "
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)
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 .
si vous devez être maximisé à la fois
ce.WindowState = Système.Windows.WindowState.Maximized;
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; }
}