UIElement и PositionAnchor в Bing картаx (Win8/WinRT)

Добавляя UIElement на карту из Bing SDK обычно используют конструкцию вида:

1
2
3
4
5
6
7
8
UIElement control;
 
//...
 
MapLayer.SetPosition(control, position);
MapLayer.SetPositionAnchor(control, new Point(0, 0));
 
map.Children.Add(control);
UIElement control;

//...

MapLayer.SetPosition(control, position);
MapLayer.SetPositionAnchor(control, new Point(0, 0));

map.Children.Add(control);

Подробнее по методам

MapLayer.SetPosition( DependencyObject dependencyObject, Location location) устанавливает позицию UIElement в географических координатах на карте.

MapLayer.SetPositionAnchor( DependencyObject dependencyObject, Point positionAnchor) устанавливает какую именно точку UIElement зафиксировать на карте в location из предыдущего метода. Это значит, что UIElement будет отрисовываться относительно нее и только точка positionAnchor попадет точно в координаты.

Расположение positionAnchor  на UIElement отсчитывается от левого верхнего угла.
(0, 0) — левый верхний угол
(control.Width, control.Height) — правый нижний угол

Если UIElement только создан и еще не был ни разу отрендерин, то размеры Width и Height могут быть равны 0. Это не даст нам возможность установить positionAnchor в правильное значение.

Узнаем Width и Height до рендеринга

1
control.Measure(new Size(int.MaxValue, int.MaxValue));
control.Measure(new Size(int.MaxValue, int.MaxValue));

void Measure(Size availableSize) вызывает рекурсивное обновление макета UIElement. После этого в свойстве DesiredSize будет содержаться размер UIElement, если его расположить на бесконечном полотне. Но полотно(родительский UIElement) можно ограничить в размере, задав параметр availableSize.

В итоге чтобы закрепить на карте правый нижний угол UIElement нужно выполнить:

1
2
3
control.Measure(new Size(int.MaxValue, int.MaxValue));
MapLayer.SetPositionAnchor(control, 
    new Point(control.DesiredSize.Width, control.DesiredSize.Height));
control.Measure(new Size(int.MaxValue, int.MaxValue));
MapLayer.SetPositionAnchor(control, 
    new Point(control.DesiredSize.Width, control.DesiredSize.Height));