private static bool TryPlacePopup(System.Windows.Controls.Primitives.Popup popup, FrameworkElement parent, FrameworkElement placementParent, FrameworkElement placementChild, PopupOrientation orientation) { var availableWidth = placementParent.ActualWidth; var availableHeight = placementParent.ActualHeight; SetActualOrientation(popup, orientation); placementChild.Measure(new Size(availableWidth, availableHeight)); var requiredWidth = placementChild.DesiredSize.Width; var requiredHeight = placementChild.DesiredSize.Height; var placementTarget = GetPlacementTarget(popup) ?? parent; var parentTransform = placementTarget.TransformToVisual(parent); var popupLocation = parentTransform.Transform(new Point(0, 0)); switch (orientation.Placement) { case PopupPlacement.Top: popupLocation.Y -= requiredHeight; break; case PopupPlacement.Bottom: popupLocation.Y += placementTarget.ActualHeight; break; case PopupPlacement.Left: popupLocation.X -= requiredWidth; break; case PopupPlacement.Right: popupLocation.X += placementTarget.ActualWidth; break; } if (orientation.Placement == PopupPlacement.Top || orientation.Placement == PopupPlacement.Bottom) { switch (orientation.HorizontalAlignment) { case PopupHorizontalAlignment.RightCenter: popupLocation.X += ((placementTarget.ActualWidth / 2) - requiredWidth); break; case PopupHorizontalAlignment.Center: popupLocation.X += ((placementTarget.ActualWidth - requiredWidth) / 2); break; case PopupHorizontalAlignment.LeftCenter: popupLocation.X += (placementTarget.ActualWidth / 2); break; case PopupHorizontalAlignment.Right: popupLocation.X += (placementTarget.ActualWidth - requiredWidth); break; } } if (orientation.Placement == PopupPlacement.Left || orientation.Placement == PopupPlacement.Right) { switch (orientation.VerticalAlignment) { case PopupVerticalAlignment.BottomCenter: popupLocation.Y += ((placementTarget.ActualHeight / 2) - requiredHeight); break; case PopupVerticalAlignment.Center: popupLocation.Y += ((placementTarget.ActualHeight - requiredHeight) / 2); break; case PopupVerticalAlignment.TopCenter: popupLocation.Y += (placementTarget.ActualHeight / 2); break; case PopupVerticalAlignment.Bottom: popupLocation.Y += (placementTarget.ActualHeight - requiredHeight); break; } } var popupLocationRelativeToPlacementParent = popupLocation; if (parent != placementParent) { var placementParentTransform = placementTarget.TransformToVisual(placementParent); popupLocationRelativeToPlacementParent = placementParentTransform.Transform(popupLocation); } if (popupLocationRelativeToPlacementParent.X < 0 || popupLocationRelativeToPlacementParent.Y < 0 || (popupLocationRelativeToPlacementParent.X + requiredWidth) > availableWidth || (popupLocationRelativeToPlacementParent.Y + requiredHeight) > availableHeight) { // not enough room return(false); } popup.HorizontalOffset = popupLocation.X; popup.VerticalOffset = popupLocation.Y; return(true); }
public static void SetActualOrientation(System.Windows.Controls.Primitives.Popup popup, PopupOrientation orientation) { //popup.AssertNotNull("popup"); popup.SetValue(ActualOrientationProperty, orientation); }