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 = ??
}
}
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;
}
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)
{
...
Je pense qu'il est plus facile d'utiliser le balisage xaml
<Window WindowStartupLocation="CenterParent">
Juste dans le code derrière.
public partial class CenteredWindow:Window
{
public CenteredWindow()
{
InitializeComponent();
WindowStartupLocation = WindowStartupLocation.CenterOwner;
Owner = Application.Current.MainWindow;
}
}
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.
J'ai trouvé celui-ci le meilleur
frmSample fs = new frmSample();
fs.Owner = this; // <-----
fs.WindowStartupLocation = WindowStartupLocation.CenterOwner;
var result = fs.ShowDialog();
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)
{
...
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;
}
Vous devez définir une fenêtre parent sur votre fenêtre (Propriétaire), puis définir la propriété WindowStartupLocation sur "CenterParent".
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();
}));
}
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();
}
XAML:
<Window WindowStartupLocation="CenterScreen">
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.
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:
Je ne sais pas s'il existe un moyen plus facile de faire cela, mais rien d'autre ne semblait fonctionner pour moi.