WPF : 응용 프로그램의 중앙에 표시 할 대화 상자 위치를 설정하는 방법은 무엇입니까?


86

.ShowDialog();메인 윈도우의 중앙에 표시하기 위해 나온 Dialog의 위치를 ​​설정하는 방법 .

이것이 제가 위치를 설정하는 방법입니다.

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

280

대화 상자에 속하는 XAML에서 :

<Window ... WindowStartupLocation="CenterOwner">

그리고 C #에서 대화 상자를 인스턴스화 할 때 :

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

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

17
실제로 var dlg = new MyDlg { Owner = this };두 번째 비트에서 할 수 있습니다.
Jodrell 2012-06-26

6
MVVM 패턴을 사용하는 경우이를 사용하여 소유자를 찾을 수 있습니다.dlg.Owner = Application.Current.MainWindow;
Jakob Busk Sørensen

56

xaml 마크 업을 사용하는 것이 더 쉽다고 생각합니다.

<Window WindowStartupLocation="CenterOwner">

부모가 MainWindow를하지 않기 때문에 아니,이 사용할 수 없습니다
왕자 OfThief

6
Window.Owner를 설정하여 모든 창을 소유자로 만들 수 있습니다.
Bogdan

10
mmm CenterParent또는 CenterOwner? CenterOwnerIntellisense 에서만 볼 수 있습니다
Brock Hensley 2013

@dirt 사용중인 WPF 버전에 따라 달라질 수 있습니다.
BrainSlugs83 2013

CenterOwner와 CenterParent는 WPF와 WinForms에서 각각
다릅니다

22

코드 뒤에 있습니다.

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

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

19

이 질문에 대한 모든 사람의 대답은 대답이 무엇인지에 대한 부분이라고 생각합니다. 이 문제에 대한 가장 쉽고 우아한 접근 방식이라고 생각하는 그것들을 간단히 정리할 것입니다.

창을 배치 할 첫 번째 설정. 여기 주인입니다.

<Window WindowStartupLocation="CenterOwner">

창을 열기 전에 소유자에게 제공해야하며 다른 게시물에서 현재 응용 프로그램의 MainWindow에 대한 정적 getter를 사용하여 MainWindow에 액세스 할 수 있습니다.

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

그게 다야.


1
Center 부모가 존재하지 않습니다.이 경우 WindowStartupLocation은 CenterOwner 여야합니다.
Umpa

1
알려 줘서 고마워. 내가 CenterParent를 넣은 이유를 모르겠습니다. 변경되었습니다.
Alex Ehlert

1
이 솔루션이 허용되지 않는 이유를 모르겠습니다. WPF가이 솔루션을 즉시 사용할 수있는 솔루션으로 사용하는 동안 계산의 골칫거리를 피할 필요가 있습니다.
cdie

2
이것이 최상의 솔루션입니다.
Beyondo

1
이 답변으로 스크롤하기 전에 정확히 이것을 수행했습니다. 가시성을 위해 +1!
Alexis Leclerc

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 Forms 부모 양식의 중앙에 배치하려면 Application.Current가 Windows Form 부모를 반환하지 않았기 때문에 부모 양식을 대화 상자에 전달했습니다 (부모 앱이 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 Form이 WPF 대화 상자를로드하는 방법은 다음과 같습니다.

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

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

2

부모 창을 창 (소유자)으로 설정 한 다음 WindowStartupLocation 속성을 "CenterParent"로 설정해야합니다.


2
사실, WPF에서 속성은 "CenterParent"가 아니라 "CenterOwner"라고합니다.
베타

2

MainWindow의 크기가 조정되거나 최대화되면 mainWindow.Width 및 mainWindow.Height가 XAML에 설정된 값을 반영하기 때문에 Fredrik Hedblad 응답에 추가하고 싶습니다.

실제 값을 원하면 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;
    }

1

XAML :

    <Window WindowStartupLocation="CenterScreen">

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.