public void Open(Point mousePos, MenuOrientationTypes orientation, int delay, FrameworkElement triggerElement, bool focusOnShow, MouseEventArgs e) { ActualTriggerElement = triggerElement; if (!OverlayPopup.IsOpen && !IsOpening) { if (this.ItemsControl.DataContext == null) this.ItemsControl.DataContext = this.DataContext; OverlayCanvas.Opacity = 0; // Make sure the root grid is hidden before it is correctly positioned IsOpening = true; if (Opening != null) Opening(triggerElement, e); OverlayPopup.IsOpen = true; //if (!OpenMenus.Contains(this)) PopupMenuManager.OpenMenus.Insert(0, this); // Add the actual menu on top of the list of open menus if (ItemsControl is Selector) (ItemsControl as Selector).SelectedIndex = -1; // Reset selected item in menu if (ParentOverlapGridBrush != null) ShowParentOverlapGrid(triggerElement); ExpandOverlayCanvas(!IsPinned); // Start opening the menu after the period of time specified by the delay parameter in milliseconds _timerOpen = new Timer(delegate { IsOpening = false; OverlayPopup.Dispatcher.BeginInvoke(delegate() { // Make sure the menu is still open. This could not be the // case if the mouse was clicked outside the menu right away. if (OverlayPopup.IsOpen && triggerElement != null) { if (!VisualTreeGenerated) // Perform only on first load { // Force content layout update OverlayPopup.IsOpen = false; OverlayPopup.IsOpen = true; } if (Showing != null) Showing(triggerElement, e); SetMenuPosition(triggerElement, orientation, mousePos); Storyboard sbOpen = OpenAnimation ?? PopupMenuUtils.CreateStoryBoard(0, OpenDuration, OverlayCanvas, "UIElement.Opacity", 1, null); sbOpen.Begin(); sbOpen.Completed += delegate { if (OverlayCanvas.Opacity == 0) // Just in case sbOpen fails to restore the opacity OverlayCanvas.Opacity = 1; if (Shown != null) Shown.BeginInvoke(triggerElement, e, null, null); // Make sure the menu stays in view after the open StoryBoard has completed SetMenuPosition(triggerElement, orientation, mousePos); }; if (focusOnShow) { ItemsControl.Focus(); _restoreFocusOnClose = true; } VisualTreeGenerated = true; } }); }, null, delay, Timeout.Infinite); } }
private void SetMenuPosition(FrameworkElement positioningElement, MenuOrientationTypes orientation, Point? mousePos) { Point ptMargin = mousePos.HasValue ? new Point(mousePos.Value.X + OffsetX, mousePos.Value.Y + OffsetY) : new Point(Canvas.GetLeft(positioningElement), Canvas.GetTop(positioningElement)); switch (orientation) { case MenuOrientationTypes.Right: ptMargin.X += positioningElement.ActualWidth - 1; break; case MenuOrientationTypes.Bottom: ptMargin.Y += positioningElement.ActualHeight; break; case MenuOrientationTypes.Left: ptMargin.X += -ContentRoot.ActualWidth - 1; break; case MenuOrientationTypes.Top: ptMargin.Y += -ContentRoot.ActualHeight; break; } // Make sure the menu stays within root layout bounds PopupMenuUtils.SetPosition(ContentRoot, ptMargin, true); }
public void OpenNextTo(FrameworkElement triggerElement, MenuOrientationTypes orientation, bool focusOnShow, bool restoreFocusOnClose) { Point mousePos = PopupMenuUtils.GetAbsoluteElementPos(PopupMenuManager.ApplicationMenus.Count == 0, triggerElement); OverlayPopup.IsOpen = IsOpening = false; // Make sure code inside the Open method is not skipped if being called simultaneously this.Open(mousePos, orientation, 0, triggerElement, focusOnShow, null); _restoreFocusOnClose = restoreFocusOnClose; }