web-dev-qa-db-fra.com

WPF: Comment définir une position de dialogue à afficher au centre de l'application?

Comment paramétrer la position de Dialog issue de .ShowDialog(); pour l'afficher au centre de la fenêtre principale.

C’est ainsi que j’essaie de définir la position.

private void Window_Loaded(object sender, RoutedEventArgs e)
{        
    PresentationSource source = PresentationSource.FromVisual(this);
    if (source != null)
    {
        Left = ??
        Top = ??
    }
}
70
Prince OfThief

Vous pouvez essayer de mettre la main sur la MainWindow dans l'événement Loaded comme ceci

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    Application curApp = Application.Current;
    Window mainWindow = curApp.MainWindow;
    this.Left = mainWindow.Left + (mainWindow.Width - this.ActualWidth) / 2;
    this.Top = mainWindow.Top + (mainWindow.Height - this.ActualHeight) / 2;
}
29
Fredrik Hedblad

Dans le XAML appartenant au dialogue:

<Window ... WindowStartupLocation="CenterOwner">

et en C # lorsque vous instanciez le dialogue:

MyDlg dlg = new MyDlg();
dlg.Owner = this;

if (dlg.ShowDialog() == true)
{
    ...
230
chessweb

Je pense qu'il est plus facile d'utiliser le balisage xaml

<Window WindowStartupLocation="CenterParent">
39
The Smallest

Juste dans le code derrière.

public partial class CenteredWindow:Window
{
    public CenteredWindow()
    {
        InitializeComponent();

        WindowStartupLocation = WindowStartupLocation.CenterOwner;
        Owner = Application.Current.MainWindow;
    }
}
19
Rob Dunbar

Je pense que les réponses de chacun à cette question font partie de ce que devrait être la réponse. Je vais simplement les mettre ensemble, ce qui, à mon avis, constitue l'approche la plus simple et la plus élégante à ce problème. 

Première configuration où vous voulez que la fenêtre soit localisée. Ici c'est le propriétaire.

<Window WindowStartupLocation="CenterOwner">

Avant d'ouvrir la fenêtre, nous devons lui en donner le propriétaire. À partir d'un autre message, nous pouvons accéder à MainWindow à l'aide du getter statique de MainWindow de l'application actuelle.

        Window window = new Window();
        window.Owner = Application.Current.MainWindow;
        window.Show();

C'est tout.

13
Alex Ehlert

J'ai trouvé celui-ci le meilleur

frmSample fs = new frmSample();
fs.Owner = this; // <-----
fs.WindowStartupLocation = WindowStartupLocation.CenterOwner;
var result = fs.ShowDialog();
8
Tim Davis

Pour qu'un dialogue WPF se positionne au centre d'un formulaire parent Windows Forms, j'ai transmis le formulaire parent à la boîte de dialogue car Application.Current n'a pas renvoyé le parent Windows Form (je suppose que cela ne fonctionne que si l'application parent est WPF).

public partial class DialogView : Window
{
    private readonly System.Windows.Forms.Form _parent;

    public DialogView(System.Windows.Forms.Form parent)
    {
        InitializeComponent();

        _parent = parent;
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        this.Left = _parent.Left + (_parent.Width - this.ActualWidth) / 2;
        this.Top = _parent.Top + (_parent.Height - this.ActualHeight) / 2;
    }
}

définissez WindowStartupLocation dans la boîte de dialogue WPF:

<Window WindowStartupLocation="CenterParent">

et la manière dont Windows Form charge la boîte de dialogue WPF est la suivante:

DialogView dlg = new DialogView();
dlg.Owner = this;

if (dlg.ShowDialog() == true)
{
    ...
3
Jason

J'aimerais ajouter à la réponse de Fredrik Hedblad que si MainWindows a été redimensionné ou agrandi, le résultat serait faux, car mainWindow.Width et mainWindow.Height reflètent les valeurs définies sur le XAML.

Si vous voulez les valeurs réelles, vous pouvez utiliser mainWindow.ActualWidth et mainWindow.ActualHeight:

private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        Application curApp = Application.Current;
        Window mainWindow = curApp.MainWindow;
        this.Left = mainWindow.Left + (mainWindow.ActualWidth - this.ActualWidth) / 2;
        this.Top = mainWindow.Top + (mainWindow.ActualHeight - this.ActualHeight) / 2;
    }
2
Nicolò Carandini

Vous devez définir une fenêtre parent sur votre fenêtre (Propriétaire), puis définir la propriété WindowStartupLocation sur "CenterParent".

2
Ugo Robain

Si vous avez peu de contrôle sur les fenêtres que vous devez afficher, l'extrait de code suivant peut être utile.

    public void ShowDialog(Window window)
    {
        Dispatcher.BeginInvoke(
            new Func<bool?>(() =>
            {
                window.Owner = Application.Current.MainWindow;
                window.WindowStartupLocation = WindowStartupLocation.CenterOwner;
                return window.ShowDialog();
            }));
    }
0
Rahul Misra

Pour la fenêtre enfant, définie sur le XAML 

WindowStartupLocation="CenterOwner"

Pour appeler votre fenêtre enfant en tant que dialogue et centre du parent, appelez-la à partir de la fenêtre parent, par exemple

private void ConfigButton_OnClick(object sender, RoutedEventArgs e)
{
    var window = new ConfigurationWindow
    {
        Owner = this
    };
    window.ShowDialog();
}
0
sky91

XAML:

    <Window WindowStartupLocation="CenterScreen">
0
GET1NE

Ce code fonctionne si vous ne souhaitez pas utiliser la propriété WindowStartupLocation dans xaml:

private void CenterWindowOnApplication()
{
    System.Windows.Application curApp = System.Windows.Application.Current;
    Window mainWindow = curApp.MainWindow;
    if (mainWindow.WindowState == WindowState.Maximized)
    {
        // Get the mainWindow's screen:
        var screen = System.Windows.Forms.Screen.FromRectangle(new System.Drawing.Rectangle((int)mainWindow.Left, (int)mainWindow.Top, (int)mainWindow.Width, (int)mainWindow.Height));
        double screenWidth = screen.WorkingArea.Width;
        double screenHeight = screen.WorkingArea.Height;
        double popupwindowWidth = this.Width;
        double popupwindowHeight = this.Height;
        this.Left = (screenWidth / 2) - (popupwindowWidth / 2);
        this.Top = (screenHeight / 2) - (popupwindowHeight / 2);
    }
    else
    {
        this.Left = mainWindow.Left + ((mainWindow.ActualWidth - this.ActualWidth) / 2;
        this.Top = mainWindow.Top + ((mainWindow.ActualHeight - this.ActualHeight) / 2);
    }
}

J'utilise "screen.WorkingArea" car la barre des tâches rend la fenêtre principale plus petite . Si vous souhaitez placer la fenêtre au milieu de l'écran, vous pouvez utiliser "screen.Bounds" à la place.

0
Markus

Par souci de documentation, je vais ajouter ici un exemple de la manière dont j'ai réalisé quelque chose de similaire. Ce dont j'avais besoin était une fenêtre contextuelle couvrant toute la zone de contenu de la fenêtre parent (à l’exception de la barre de titre), mais le simple fait de centrer la boîte de dialogue et d’en étendre le contenu ne fonctionnait pas, car elle était toujours légèrement décalée du bas.

Remarque sur l'expérience utilisateur: Ce n'est pas agréable de ne pas pouvoir faire glisser/fermer la fenêtre parente lorsque la boîte de dialogue sans bordure est affichée, aussi je reconsidérerais son utilisation. J'ai aussi décidé de ne pas le faire après la publication de cette réponse, mais je laisserai les autres personnes libres de regarder.

Après quelques recherches sur Google et des tests, j'ai finalement réussi à le faire comme ceci:

var dialog = new DialogWindow
{
    //this = MainWindow
    Owner = this
};

dialog.WindowStartupLocation = WindowStartupLocation.Manual;
dialog.WindowStyle = WindowStyle.None;
dialog.ShowInTaskbar = false;
dialog.ResizeMode = ResizeMode.NoResize;
dialog.AllowsTransparency = true;

var ownerContent = (FrameworkElement) Content;
dialog.MaxWidth = ownerContent.ActualWidth;
dialog.Width = ownerContent.ActualWidth;
dialog.MaxHeight = ownerContent.ActualHeight;
dialog.Height = ownerContent.ActualHeight;    

var contentPoints = ownerContent.PointToScreen(new Point(0, 0));
dialog.Left = contentPoints.X;
dialog.Top = contentPoints.Y;

dialog.ShowDialog();

La DialogWindow est une fenêtre et son propriétaire est défini sur la fenêtre principale de l'application. La WindowStartupLocation doit être définie sur Manual pour que le positionnement manuel fonctionne.

Résultat:

 No dialog showing 

 Modal dialog showing 

Je ne sais pas s'il existe un moyen plus facile de faire cela, mais rien d'autre ne semblait fonctionner pour moi.

0
Shahin Dohan