Могу ли я сказать в коде позади, если всплывающее окно было перемещено относительно его цели размещения? - PullRequest
1 голос
/ 07 февраля 2012

Я работаю над проектом WPF, в котором у меня есть сетка миниатюр (каждая миниатюра - это SurfaceButton), и нажатие на каждую миниатюру показывает свое собственное всплывающее меню.Всплывающее меню в каждом случае имеет свою миниатюрную фотографию в качестве цели размещения.Миниатюра и всплывающее окно располагаются рядом друг с другом в сетке.

Я разработал всплывающее окно, чтобы имитировать вид всплывающего прокручиваемого меню, которое вы найдете в iOS, в комплекте с маленькой треугольной стрелкой, которая указывает наминиатюра, к которой относится всплывающее окно (всплывающее окно появляется под миниатюрой).

Но, к моему большому удивлению, если вы нажмете на миниатюру, расположенную внизу экрана, WPF переместит всплывающее окно надминиатюру, чтобы она не была за кадром.

Это здорово, но как я могу сравнить положения двух элементов и соответственно переместить стрелку (или скрыть ее и показать другой), чтобы всплывающее окно надthumbnail указывает вниз?

Надеюсь, что это имеет какой-то смысл!

Я пробовал VisualTreeHelper.GetOffset, но он возвращает только смещение от родителя элемента, и кажется, что оно всегда0,0 или 1,1.Я также пробовал UIElement.PointToScreen, но числа, которые я получаю от двух элементов, похоже, не меняются, когда всплывающее окно перемещается.

Я уверен, что есть простое решение, которое я пропускаю.

1 Ответ

0 голосов
/ 11 сентября 2017

Вы можете получить фактическое размещение вашего всплывающего окна, как показано ниже

// ComboBox for example:
Popup popup = yourcombobox.Template.FindName("PART_Popup", yourcombobox) as Popup;

popup.Opened += (s, a) => {
    // structure inside will be different by your templates
    Dacorator decorator = (s as popup).Child as Decorator;
    Border border = decorator.Child as Border;
    Double y0 = yourcombobox.PointToScreen(new Point(0,0)).Y;
    Double y1 = border.PointToScreen(new Point(0,0)).Y;
    if(y0 > y1) {
        // when shows at the top
        yourcombobox.Background = Brushes.Red;
    } else {
        // when shows at the botttom
        yourcombobox.Background = Brushes.Blue;
    }
};

У всплывающего окна нет собственного размера или позиции, поэтому вы должны отслеживать позицию ребенка только тогда, когда отображается всплывающее окно. https://docs.microsoft.com/en-us/dotnet/framework/wpf/controls/popup-overview

...