Управление всплывающим окном WPF — поиск координат X, Y

Я пытаюсь получить координаты X, Y всплывающего элемента управления. Я пытался:

VisualTreeHelper.GetOffset(Всплывающее окно);

но возвращаемый вектор всегда содержит (0,0) для X и Y.

Родителем всплывающего окна является корень макета, представляющий собой сетку.

CustomPopupPlacementCallback также всегда возвращает 0,0 для своего параметра Point.

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

--------------------Обновлять--------------------

Крис Никол, я попробовал ваш ответ со следующим кодом, но все равно получил 0,0 для rootPoint:

Xaml:

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Test.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="800" Height="600">    

<Grid x:Name="LayoutRoot">
    <Popup x:Name="Popup" IsOpen="True" Placement="Center" Width="100" Height="100">
        <Button Click="Button_Click" Content="Test" />
    </Popup>
</Grid>

Code Behind:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        this.InitializeComponent();

        // Insert code required on object creation below this point.
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        GeneralTransform transform = Popup.TransformToAncestor(LayoutRoot);
        Point rootPoint = transform.Transform(new Point(0, 0));
    }
}

person gamzu07    schedule 12.01.2010    source источник
comment
У меня такая же проблема, вы нашли решение? С уважением   -  person Cinaird    schedule 15.07.2010
comment
Я не нашел решения. Извините за долгую задержку.   -  person gamzu07    schedule 04.05.2011
comment
Хорошо, спасибо за ответы   -  person Cinaird    schedule 05.05.2011


Ответы (2)


Не уверен, что это лучший способ выяснить это, но он работает:

GeneralTransform transform = controlToFind.TransformToAncestor(TopLevelControl);
            Point rootPoint = transform.Transform(new Point(0, 0));
person Chris Nicol    schedule 12.01.2010
comment
Да, это это лучший способ сделать это. Обычно я делаю это одной строкой: controlToFind.TransformToAncestor(TopLevelControl).Transform(new Point(0,0)) - person Ray Burns; 13.01.2010
comment
да, я тоже делаю это в одну строку. Я просто разделил это для примера, чтобы было легче понять - person Chris Nicol; 13.01.2010
comment
Спасибо за помощь, проверьте мое обновление, если у вас есть время. - person gamzu07; 13.01.2010
comment
Я попытался использовать метод TransformToAncestor в обработчике событий ContextMenu.OnMenuOpened и получил исключение. Указанный визуал не является предком этого визуала. - person Rudolf Dvoracek; 07.06.2019

Вы должны использовать win32 API:

добавьте это в свой класс:

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

    [StructLayout(LayoutKind.Sequential)]
    private struct RECT
    {
        public int Left; // X coordinate of topleft point
        public int Top; // Y coordinate of topleft point
        public int Right; // X coordinate of bottomright point
        public int Bottom; // Y coordinate of bottomright point
    }

для нахождения координат X, Y введите это в свой код (в прямом направлении вы запросили координаты):

        IntPtr handle = (PresentationSource.FromVisual(popup.Child) as HwndSource).Handle;

        RECT rect = new RECT();
        GetWindowRect(handle, out rect);
person JanSkalicky    schedule 02.04.2012
comment
Это решение только для оконных форм и типичных окон, а не для WPF/Xaml. - person VoidVolker; 23.10.2018