Как установить расположение дочернего окна, но не в центре окна владельца в WPF [РЕШЕНО!]

#c# #wpf #location

Вопрос:

Итак, я разрабатываю игру в кости, у меня есть окно игры и окно сообщения, которое открывается, когда мне нужен диалог. Я нашел, как заставить окно сообщения отображаться в центре его владельца с помощью WindowStartupLocation=»Владелец центра», проблема в том, что оно скрывает кости, отображаемые в окне игры, и для некоторых сообщений, таких как «Поздравляю, у вас есть серия! Вы выигрываете 2500 очков, но ваш ход заканчивается здесь» Я бы очень хотел, чтобы игрок мог увидеть свою счастливую и очень редкую серию, прежде чем он нажмет кнопку «завершить ход», которая сбросит отображение кубиков для следующего игрока.

Мой вопрос в том, есть ли способ установить расположение дочернего окна немного выше, чем в центре его владельца, без его жесткого кодирования? Я чувствую, что если я жестко закодирую его, присвоив значение его верхним и левым атрибутам, в то время как мое игровое окно настроено на центральный экран, расположение сообщения внутри игрового окна изменится в зависимости от экрана пользователя.

С тех пор как я нашел способ центрировать свое «Домашнее» окно (я не знаю, как его назвать по-английски…), поскольку оно изменяется по высоте, я надеялся, что есть способ сделать что-то подобное с моим окном сообщений… дело в том, что оно не изменяется, поэтому я не могу использовать найденный метод… Тем не менее, вот метод, используемый для моего «Домашнего» окна, может быть, это поможет придумать идею?

 protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
        {
            base.OnRenderSizeChanged(sizeInfo);

            this.Top  = (sizeInfo.PreviousSize.Height - sizeInfo.NewSize.Height) / 2;
        }
 

Ответ №1:

Я обычно использую логику, подобную этой, чтобы мои диалоговые окна сообщений отображались на экране немного выше, чем в центре, основываясь на моей математике в главном окне приложения. Логика немного грубовата, но она работает для меня.

Я могу взять эти координаты и ввести их в функцию, которая показывает диалоговое окно. Если вы не можете управлять своими диалоговыми окнами таким образом, вы можете использовать подобную логику в обработчике Loaded событий диалогового окна

 var win  = Application.Current.MainWindow;                     
var left = win.Left   Math.Max(win.ActualWidth  / 2 - 100, 0);
var top  = win.Top   Math.Max(win.ActualHeight / 4 - 50,  0);
var loc  = WindowStartupLocation.Manual;
 

Комментарии:

1. Спасибо, Джо! Я поступил не совсем так, как ты предлагал, но ты показал мне путь! Вот что я придумал: private void Window_Loaded(object sender, RoutedEventArgs e) { this.Top = Owner.Top (Owner.ActualHeight/4 - this.ActualHeight/2); this.Left = Owner.Left (Owner.ActualWidth/2 - this.ActualWidth/2); } поскольку в моем окне сообщений было установлено игровое окно в качестве владельца, я мог получить информацию о размере и местоположении, необходимую для размещения в соответствии с местоположением игрового окна, даже если игрок переместит его! 😀