WPF:アプリケーションの中央に表示するダイアログの位置を設定するにはどうすればよいですか?


83

.ShowDialog();メインウィンドウの中央に表示するようになったダイアログの位置を設定する方法 。

これが私が位置を設定しようとする方法です。

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

回答:


35

このように、LoadedイベントでMainWindowを取得しようとすることができます

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

8
これにより、左上隅が中央に配置されます。受け入れられなかったこの答えは、OPの願いをより正確に達成します。
Chris Schiffhauer 2015

277

ダイアログに属するXAMLの場合:

<Window ... WindowStartupLocation="CenterOwner">

ダイアログをインスタンス化するときのC#では:

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

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

17
実際var dlg = new MyDlg { Owner = this };には2番目のビットで行うことができます。
ジョドレル2012年

6
MVVMパターンを使用している場合は、これを使用して所有者を見つけることができます。dlg.Owner = Application.Current.MainWindow;
JakobBuskSørensen 2018年

55

xamlマークアップを使用する方が簡単だと思います

<Window WindowStartupLocation="CenterOwner">

いいえ、親がメインウィンドウではないため、これを使用できません
Prince OfThief 2010年

6
Window.Ownerを設定することで、任意のウィンドウを所有者にすることができます。
ボグダン2012年

10
うーんCenterParentまたはCenterOwnerCenterOwnerIntellisenseでのみ表示
Brock Hensley 2013

@dirtは、使用しているWPFのバージョンによって異なる場合があります。
BrainSlugs83 2013年

CenterOwnerとCenterParentは、それぞれ、WPFとリサイズの間で異なっている
F8ER

21

ちょうどコードビハインドで。

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

        WindowStartupLocation = WindowStartupLocation.CenterOwner;
        Owner = Application.Current.MainWindow;
    }
}

19

この質問に対する皆さんの答えは、答えがどうあるべきかという部分だと思います。この問題への最も簡単でエレガントなアプローチであると私が信じるそれらを簡単にまとめます。

ウィンドウを配置する最初のセットアップ。こちらがオーナーです。

<Window WindowStartupLocation="CenterOwner">

ウィンドウを開く前に、所有者を指定する必要があります。別の投稿から、現在のアプリケーションのMainWindowの静的ゲッターを使用してMainWindowにアクセスできます。

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

それでおしまい。


1
センターの親が存在しません。この場合、WindowStartupLocationはCenterOwnerである必要があります。
umpa 2017年

1
知らせてくれてありがとうございます。CenterParentを配置した理由がわかりません。変更されました。
Alex

1
このソリューションが受け入れられない理由はわかりません
。WPF

2
これが最善の解決策です。
beyondo 2018

1
この答えにスクロールする前に、私はまさにこれを行うことになりました。視認性のために+1!
アレクシス・ルクレール

8

私はこれが最高だと思いました

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

5

表示する必要のあるウィンドウをほとんど制御できない場合は、次のスニペットが役立つ場合があります

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

なぜこれがあまり賛成票を獲得していないのだろうか。私にとって、これはどのように行われるべきかです。所有者を中央に配置するには、所有者を割り当てる必要があります。そうすれば、ハッキングなしで機能します。
VPZ

3

WPFダイアログをWindowsフォームの親フォームの中央に配置するには、Application.CurrentがWindowsフォームの親を返さなかったため、親フォームをダイアログに渡しました(親アプリが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;
    }
}

WPFダイアログでWindowStartupLocationを設定します。

<Window WindowStartupLocation="CenterParent">

WindowsフォームがWPFダイアログをロードする方法は次のようになります。

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

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

2

親ウィンドウをウィンドウ(所有者)に設定してから、WindowStartupLocationプロパティを「CenterParent」に設定する必要があります


2
確かに、WPFでは、プロパティは「CenterParent」ではなく「CenterOwner」と呼ばれます。
ベータ版

2

MainWindow.WidthとmainWindow.HeightはXAMLに設定されている値を反映しているため、MainWindowsのサイズが変更されたり最大化されたりすると、結果が間違ってしまうというFredrikHedbladの応答に追加したいと思います。

実際の値が必要な場合は、mainWindow.ActualWidthおよび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;
    }


0

このコードは、xamlでWindowStartupLocationプロパティを使用したくない場合に機能します。

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

タスクバーによってmainWindowが小さくなるため、「screen.WorkingArea」を使用しています。ウィンドウを画面の中央に配置する場合は、代わりに「screen.Bounds」を使用できます。


0

子ウィンドウの場合、XAMLで設定します

WindowStartupLocation="CenterOwner"

子ウィンドウをダイアログおよび親の中心として呼び出すには、親ウィンドウから呼び出します。例:

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

0

ドキュメントのために、私がどのようにして同様のことを達成したかの例をここに追加します。必要なのは、親ウィンドウのコンテンツ領域全体(タイトルバーを除く)をカバーするポップアップでしたが、ダイアログは常に下から少しオフセットされているため、ダイアログを中央に配置してコンテンツを拡大するだけでは機能しませんでした。

ユーザーエクスペリエンスに関する注意:ボーダレスダイアログが表示されているときに親ウィンドウをドラッグ/閉じることができないのは良くないので、それを使用することを再検討します。また、この回答を投稿した後、これを行わないことにしましたが、他の人が見ることができるようにしておきます。

いくつかのグーグルとテストの後、私はついに次のようにそれを行うことができました:

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();

DialogWindowウィンドウであり、その所有者は、アプリケーションのメインウィンドウに設定されています。WindowStartupLocationに設定する必要がありますManual、作業への手動位置決めのために。

結果:

ダイアログが表示されない

表示するモーダルダイアログ

これを行うもっと簡単な方法があるかどうかはわかりませんが、他に何もうまくいかないようでした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.