private static Point CalculateLocation(AdornerLocation anchor, Size adorneeSize, Size adornerSize) { Point location = new Point(); switch (anchor) { case AdornerLocation.BottomRight: location = new Point(adorneeSize.Width, 0); break; case AdornerLocation.TopRight: location = new Point(adorneeSize.Width, -adornerSize.Height); break; case AdornerLocation.TopLeft: location = new Point(adorneeSize.Width - adornerSize.Width, -adornerSize.Height); break; case AdornerLocation.BottomLeft: location = new Point(adorneeSize.Width - adornerSize.Width, 20); break; } return(location); }
protected override Size ArrangeOverride(Size finalSize) { Point anchorPoint = this.AdornedElement.TranslatePoint(new Point(this.AdornedElement.RenderSize.Width, 0), this.ScrollViewer); AdornerLocation anchor = AnnotationAdorner.GetAnchor(this); if (anchor == AdornerLocation.None) { // Calculate based on the real size of the adorner, depending on current zoom level DesignerView designerView = ((WorkflowViewElement)AdornedElement).Context.Services.GetService <DesignerView>(); double zoomLevel = designerView.ZoomFactor; Size adornerSize = new Size(this.content.DesiredSize.Width * zoomLevel, this.content.DesiredSize.Height * zoomLevel); anchor = FindAnchor(anchorPoint, adornerSize, new Rect(0, 0, this.ScrollViewer.ViewportWidth, this.ScrollViewer.ViewportHeight)); AnnotationAdorner.SetAnchor(this, anchor); } Point location = CalculateLocation(anchor, this.AdornedElement.RenderSize, this.content.DesiredSize); this.content.Arrange(new Rect(location, finalSize)); return(finalSize); }
// (3) | (2) // ______|______ // (4) | (1) // | // canvas is divided into four areas by anchorPoint // try to figure out which area could fit desiredSize from area1 to area4, if there's no fit, default to area4. internal static AdornerLocation FindAnchor(Point anchorPoint, Size desiredSize, Rect canvas) { Fx.Assert(anchorPoint.X >= canvas.X && anchorPoint.X <= canvas.X + canvas.Width, "X axis of anchorPoint not within canvas"); Fx.Assert(anchorPoint.Y >= canvas.Y && anchorPoint.Y <= canvas.Y + canvas.Height, "Y axis of anchorPoint not within canvas"); AdornerLocation anchor = AdornerLocation.None; // try area 1 and 2 if (anchorPoint.X + desiredSize.Width <= canvas.X + canvas.Width) { // area 1 if (anchorPoint.Y + desiredSize.Height <= canvas.Y + canvas.Height) { anchor = AdornerLocation.BottomRight; } // area 2 if (anchor == AdornerLocation.None && anchorPoint.Y - desiredSize.Height >= canvas.Y) { anchor = AdornerLocation.TopRight; } } // area 3 if (anchor == AdornerLocation.None && anchorPoint.X - desiredSize.Width >= canvas.X && anchorPoint.Y - desiredSize.Height >= canvas.Y) { anchor = AdornerLocation.TopLeft; } // default to area 4 if (anchor == AdornerLocation.None) { anchor = AdornerLocation.BottomLeft; } return(anchor); }
public static void SetAnchor(DependencyObject obj, AdornerLocation anchor) { obj.SetValue(AnnotationAdorner.AnchorProperty, anchor); }
private static Point CalculateLocation(AdornerLocation anchor, Size adorneeSize, Size adornerSize) { Point location = new Point(); switch (anchor) { case AdornerLocation.BottomRight: location = new Point(adorneeSize.Width, 0); break; case AdornerLocation.TopRight: location = new Point(adorneeSize.Width, -adornerSize.Height); break; case AdornerLocation.TopLeft: location = new Point(adorneeSize.Width - adornerSize.Width, -adornerSize.Height); break; case AdornerLocation.BottomLeft: location = new Point(adorneeSize.Width - adornerSize.Width, 20); break; } return location; }