internal static CustomPopupPlacement[] PositionPopup( CustomPlacementMode placement, Size popupSize, Size targetSize, Point offset, FrameworkElement child = null) { Matrix transformToDevice = default; if (child != null) { Helper.TryGetTransformToDevice(child, out transformToDevice); } CustomPopupPlacement preferredPlacement = CalculatePopupPlacement(placement, popupSize, targetSize, offset, child, transformToDevice); CustomPopupPlacement?alternativePlacement = null; var alternativePlacementMode = GetAlternativePlacementMode(placement); if (alternativePlacementMode.HasValue) { alternativePlacement = CalculatePopupPlacement(alternativePlacementMode.Value, popupSize, targetSize, offset, child, transformToDevice); } if (alternativePlacement.HasValue) { return(new[] { preferredPlacement, alternativePlacement.Value }); } else { return(new[] { preferredPlacement }); } }
private static CustomPlacementMode?GetAlternativePlacementMode(CustomPlacementMode placement) { switch (placement) { case CustomPlacementMode.Top: return(CustomPlacementMode.Bottom); case CustomPlacementMode.Bottom: return(CustomPlacementMode.Top); case CustomPlacementMode.Left: return(CustomPlacementMode.Right); case CustomPlacementMode.Right: return(CustomPlacementMode.Left); case CustomPlacementMode.Full: return(null); case CustomPlacementMode.TopEdgeAlignedLeft: return(CustomPlacementMode.BottomEdgeAlignedLeft); case CustomPlacementMode.TopEdgeAlignedRight: return(CustomPlacementMode.BottomEdgeAlignedRight); case CustomPlacementMode.BottomEdgeAlignedLeft: return(CustomPlacementMode.TopEdgeAlignedLeft); case CustomPlacementMode.BottomEdgeAlignedRight: return(CustomPlacementMode.TopEdgeAlignedRight); case CustomPlacementMode.LeftEdgeAlignedTop: return(CustomPlacementMode.RightEdgeAlignedTop); case CustomPlacementMode.LeftEdgeAlignedBottom: return(CustomPlacementMode.RightEdgeAlignedBottom); case CustomPlacementMode.RightEdgeAlignedTop: return(CustomPlacementMode.RightEdgeAlignedTop); case CustomPlacementMode.RightEdgeAlignedBottom: return(CustomPlacementMode.LeftEdgeAlignedBottom); //case CustomPopupPlacementMode.Auto: default: return(null); } }
private static CustomPopupPlacement CalculatePopupPlacement( CustomPlacementMode placement, Size popupSize, Size targetSize, Point offset, FrameworkElement child = null, Matrix transformToDevice = default) { Point point; PopupPrimaryAxis primaryAxis; switch (placement) { case CustomPlacementMode.Top: point = new Point((targetSize.Width - popupSize.Width) / 2, -popupSize.Height); primaryAxis = PopupPrimaryAxis.Horizontal; break; case CustomPlacementMode.Bottom: point = new Point((targetSize.Width - popupSize.Width) / 2, targetSize.Height); primaryAxis = PopupPrimaryAxis.Horizontal; break; case CustomPlacementMode.Left: point = new Point(-popupSize.Width, (targetSize.Height - popupSize.Height) / 2); primaryAxis = PopupPrimaryAxis.Vertical; break; case CustomPlacementMode.Right: point = new Point(targetSize.Width, (targetSize.Height - popupSize.Height) / 2); primaryAxis = PopupPrimaryAxis.Vertical; break; case CustomPlacementMode.Full: point = new Point((targetSize.Width - popupSize.Width) / 2, (targetSize.Height - popupSize.Height) / 2); primaryAxis = PopupPrimaryAxis.None; break; case CustomPlacementMode.TopEdgeAlignedLeft: point = new Point(0, -popupSize.Height); primaryAxis = PopupPrimaryAxis.Horizontal; break; case CustomPlacementMode.TopEdgeAlignedRight: point = new Point(targetSize.Width - popupSize.Width, -popupSize.Height); primaryAxis = PopupPrimaryAxis.Horizontal; break; case CustomPlacementMode.BottomEdgeAlignedLeft: point = new Point(0, targetSize.Height); primaryAxis = PopupPrimaryAxis.Horizontal; break; case CustomPlacementMode.BottomEdgeAlignedRight: point = new Point(targetSize.Width - popupSize.Width, targetSize.Height); primaryAxis = PopupPrimaryAxis.Horizontal; break; case CustomPlacementMode.LeftEdgeAlignedTop: point = new Point(-popupSize.Width, 0); primaryAxis = PopupPrimaryAxis.Vertical; break; case CustomPlacementMode.LeftEdgeAlignedBottom: point = new Point(-popupSize.Width, targetSize.Height - popupSize.Height); primaryAxis = PopupPrimaryAxis.Vertical; break; case CustomPlacementMode.RightEdgeAlignedTop: point = new Point(targetSize.Width, 0); primaryAxis = PopupPrimaryAxis.Vertical; break; case CustomPlacementMode.RightEdgeAlignedBottom: point = new Point(targetSize.Width, targetSize.Height - popupSize.Height); primaryAxis = PopupPrimaryAxis.Vertical; break; //case CustomPopupPlacementMode.Auto: default: throw new ArgumentOutOfRangeException(nameof(placement)); } if (child != null) { Vector childOffset = VisualTreeHelper.GetOffset(child); if (transformToDevice != default) { childOffset = transformToDevice.Transform(childOffset); } point -= childOffset; } return(new CustomPopupPlacement(point, primaryAxis)); }
public static void SetPlacement(DependencyObject element, CustomPlacementMode value) { element.SetValue(PlacementProperty, value); }