2009-12-31 2 views
0

У меня есть средство просмотра прокрутки в моем приложении, которое содержит холст, в котором у меня есть дерево, построенное на основе дерева. Я пытаюсь получить позицию конкретного элемента узла в холсте относительно средства просмотра прокрутки (чтобы я мог прокручивать его), но мои попытки не работают.TranslatePoint в пределах холста

Я пробовал использовать marker.TranslatePoint(new Point(0, 0), scrollViewer) (где - элемент на холсте), но это просто возвращает положение холста, а не маркер. Аналогично, если я попробую marker.TranslatePoint(new Point(0, 0), layoutCanvas), я всегда получаю (0,0) как результат, независимо от того, где на самом деле находится маркер.

Вот мой код:

var marker = m_Metadata[node].Marker; 
var location = marker.TranslatePoint(new Point(0, 0), scrollViewer); // This inorrectly gives the position of the canvas, rather than the marker. 
var size = new Size(marker.Width, marker.Height); 
var markerArea = new Rect(location, size); 

double horizontalOffset = (markerArea.Right + markerArea.Left - scrollViewer.ViewportWidth)/2; 
double verticalOffset = (markerArea.Bottom + markerArea.Top - scrollViewer.ViewportHeight)/2; 

Я также попытался с помощью marker.TransformToVisual(scrollViewer).Transform(new Point(0, 0), но это дает те же результаты.

Я могу обойти его, используя Canvas.GetLeft, Canvas.GetTop и др., Но это грязно и запутанно (поскольку они не всегда будут выровнены по левому краю и выровнены по высоте).

Как я могу исправить это, или он просто не работает для холстов?

+0

Вопрос: не позволяет ли холст выровнять элементы на основе смещения сверху и слева? Вы не можете выровнять по правому краю или снизу на холсте. Возможно, я ошибаюсь ... –

+0

Нет, вы также можете использовать Canvas.SetBottom и Canvas.SetRight. –

ответ

1

Я написал простой обходной метод для этой проблемы. Он работает, но он не очень чист, поэтому, если у кого-то есть ответ на этот вопрос, я все равно его ценю! Вот код, который я использую в настоящее время:

private static Point GetCanvasChildPosition(FrameworkElement element) 
{ 
    var canvas = element.Parent as Canvas; 

    double left = Canvas.GetLeft(element); 
    double top = Canvas.GetTop(element); 

    bool isLeftAligned = !double.IsNaN(left); 
    bool isTopAligned = !double.IsNaN(top); 

    double x; 
    double y; 

    if (isLeftAligned) 
    { 
     x = left; 
    } 
    else 
    { 
     x = canvas.Width - Canvas.GetRight(element) - element.Width; 
    } 

    if (isTopAligned) 
    { 
     y = top; 
    } 
    else 
    { 
     y = canvas.Height - Canvas.GetBottom(element) - element.Height; 
    } 

    return new Point(x, y); 
} 
1

Вы пытались использовать VisualTreeHelper.GetOffset(Visual obj)? Я не нахожусь перед Студией, но, похоже, я вспоминал об использовании этого только для такого рода вещей в прошлом ...

+0

Это просто дает (0,0), как и прежде, к сожалению. –

+0

Хм ... это может показаться глупым вопросом, но когда код, который вы написали, называется? Обработчик событий, инициированный пользователем? При инициализации? Строительство? и т.д? Ответ, который я нащупываю здесь, может быть, вы пытаетесь собрать детали на бите пользовательского интерфейса, который еще не закончил компоновку ... – JerKimball

+0

В основном я пытаюсь перевести его на текущий выбранный узел. Это всегда будет происходить в результате взаимодействия с пользователем, но в какой момент дерево было правильно отображено. –