WPF Получить элемент по определенным координатам

У меня есть метки внутри холста, мне нужно получить метку, которая пересекается с координатами X, Y?

Спасибо!!


person Community    schedule 21.07.2011    source источник
comment
Координаты относительно холста? Окно? Экран? Относительно верхнего левого угла? Нижний левый? Другой?   -  person Jeff Mercado    schedule 21.07.2011


Ответы (2)


Canvas.GetLeft(element), Canvas.GetTop(element) даст вам позицию любого элемента. Используйте ActualWidth и ActualHeight, чтобы сформировать полный прямоугольник. Вы можете перебирать Children of the Canvas с помощью foreach.

Редактировать: CodeNaked указал, что элементы могут быть установлены с помощью SetRight или SetBottom, поэтому я изменил пример кода:

foreach (FrameworkElement nextElement in myCanvas.Children)
{
    double left = Canvas.GetLeft(nextElement);
    double top = Canvas.GetTop(nextElement);
    double right = Canvas.GetRight(nextElement);
    double bottom = Canvas.GetBottom(nextElement);
    if (double.IsNaN(left))
    {
        if (double.IsNaN(right) == false)
            left = right - nextElement.ActualWidth;
        else
            continue;
    }
    if (double.IsNaN(top))
    {
        if (double.IsNaN(bottom) == false)
            top = bottom - nextElement.ActualHeight;
        else
            continue;
    }
    Rect eleRect = new Rect(left, top, nextElement.ActualWidth, nextElement.ActualHeight);
    if (myXY.X >= eleRect.X && myXY.Y >= eleRect.Y && myXY.X <= eleRect.Right && myXY.Y <= eleRect.Bottom)
    {
        // Add to intersects list
    }
}
person Ed Bayiates    schedule 21.07.2011
comment
Вы предполагаете, что OP не использует Справа или снизу прикрепленные свойства. - person CodeNaked; 21.07.2011
comment
@CodeNaked: в комментариях к вопросу говорится, что они смотрят в верхнем левом углу. - person Scott Boettger; 21.07.2011
comment
@Scott - в комментарии говорится, что координаты X / Y относятся к левому верхнему углу, а не к тому, что он использует присоединенные свойства Top и Left. В любом случае я проголосовал за этот ответ, так как он на высоте. - person CodeNaked; 21.07.2011
comment
@AresAvatar - Нет, нет. Каждое присоединенное свойство используется по-разному в Canvas.ArrangeOverride. Установка присоединенного свойства Right не влияет на свойство Left. - person CodeNaked; 21.07.2011
comment
Спасибо! Интересно, почему в WPF нет такой функции, как hitTest! - person ; 22.07.2011

Просто используйте InputHitTest на своем холсте, передав координата, которую вы хотите в качестве параметра. Обратите внимание, что InputHitTest доступен на каждом UIElement и не зависит от холста.

person Julien Lebosquain    schedule 21.07.2011
comment
Я не думаю, что это получает все элементы, если точка X, Y перекрывает более одного ребенка. - person Ed Bayiates; 21.07.2011
comment
Вы правы, это не так (вопрос подразумевает, что это не нужно, хотя и получите ярлык). Однако он будет учитывать поля и z-порядок, округление макета, ... - person Julien Lebosquain; 22.07.2011
comment
Истинный. +1 за простоту. - person Ed Bayiates; 22.07.2011
comment
Argh, я потратил так много времени, пытаясь создать хороший рабочий пример. Однако есть некоторые предостережения: тест на попадание вернет листья визуального дерева. Таким образом, он вернет не метку, а TextBlock (или другой), представляющий содержимое. Использование метода VisualTreeHelper.HitTest() должно помочь в этом, но имеет другую проблему. , он фактически пропустит метки в тесте на попадание. Решение, которое я нашел (которое заняло большую часть моего времени), состоит в том, чтобы выполнить поиск визуального дерева самостоятельно. - person Jeff Mercado; 22.07.2011
comment
Вы можете использовать HitTesting в WPF для обхода нескольких элементов, даже если они перекрываются. Вы используете VisualTreeHelper.HitTest с обратным вызовом. Например, взгляните на этот тестовый код ответа SO: 6770950" title="присоединяемые окна, плавающее окно и интеграция меню главного окна"> stackoverflow.com/questions/6410146/ - person NathanAW; 22.07.2011
comment
@Nathan: Хотя и с учетом проблемы, о которой я упоминал в своем предыдущем комментарии. - person Jeff Mercado; 22.07.2011