/// <summary> /// Implements custom placement for ribbon popup /// </summary> /// <param name="popupsize"></param> /// <param name="targetsize"></param> /// <param name="offset"></param> /// <returns></returns> private CustomPopupPlacement[] CustomPopupPlacementMethod(Size popupsize, Size targetsize, Point offset) { if (this.DropDownPopup == null || this.SelectedTabItem == null) { return(null); } // Get current workarea var tabItemPos = this.SelectedTabItem.PointToScreen(new Point(0, 0)); var tabItemRect = new RECT { left = (int)tabItemPos.X, top = (int)tabItemPos.Y, right = (int)tabItemPos.X + (int)this.SelectedTabItem.ActualWidth, bottom = (int)tabItemPos.Y + (int)this.SelectedTabItem.ActualHeight }; const uint MONITOR_DEFAULTTONEAREST = 0x00000002; var monitor = NativeMethods.MonitorFromRect(ref tabItemRect, MONITOR_DEFAULTTONEAREST); if (monitor == IntPtr.Zero) { return(null); } var monitorInfo = new MONITORINFO(); monitorInfo.cbSize = Marshal.SizeOf(monitorInfo); UnsafeNativeMethods.GetMonitorInfo(monitor, monitorInfo); var startPoint = this.PointToScreen(new Point(0, 0)); if (this.FlowDirection == FlowDirection.RightToLeft) { startPoint.X -= this.ActualWidth; } var inWindowRibbonWidth = monitorInfo.rcWork.right - Math.Max(monitorInfo.rcWork.left, startPoint.X); var actualWidth = this.ActualWidth; if (startPoint.X < monitorInfo.rcWork.left) { actualWidth -= monitorInfo.rcWork.left - startPoint.X; startPoint.X = monitorInfo.rcWork.left; } // Set width and prevent negative values this.DropDownPopup.Width = Math.Max(0, Math.Min(actualWidth, inWindowRibbonWidth)); return(new[] { new CustomPopupPlacement(new Point(startPoint.X - tabItemPos.X + offset.X, targetsize.Height + offset.Y), PopupPrimaryAxis.Vertical), new CustomPopupPlacement(new Point(startPoint.X - tabItemPos.X + offset.X, -1 * (targetsize.Height + offset.Y + ((ScrollViewer)this.SelectedContent).ActualHeight)), PopupPrimaryAxis.Vertical) }); }
/// <summary> /// Implements custom placement for ribbon popup /// </summary> /// <param name="popupsize"></param> /// <param name="targetsize"></param> /// <param name="offset"></param> /// <returns></returns> private CustomPopupPlacement[] CustomPopupPlacementMethod(Size popupsize, Size targetsize, Point offset) { if (this.DropDownPopup != null && this.SelectedTabItem != null) { // Get current workarea var tabItemPos = this.SelectedTabItem.PointToScreen(new Point(0, 0)); var tabItemRect = new NativeMethods.Rect { Left = (int)tabItemPos.X, Top = (int)tabItemPos.Y, Right = (int)tabItemPos.X + (int)this.SelectedTabItem.ActualWidth, Bottom = (int)tabItemPos.Y + (int)this.SelectedTabItem.ActualHeight }; const uint MONITOR_DEFAULTTONEAREST = 0x00000002; var monitor = NativeMethods.MonitorFromRect(ref tabItemRect, MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { var monitorInfo = new NativeMethods.MonitorInfo(); monitorInfo.Size = Marshal.SizeOf(monitorInfo); NativeMethods.GetMonitorInfo(monitor, monitorInfo); var startPoint = this.PointToScreen(new Point(0, 0)); if (this.FlowDirection == FlowDirection.RightToLeft) { startPoint.X -= this.ActualWidth; } var inWindowRibbonWidth = monitorInfo.Work.Right - Math.Max(monitorInfo.Work.Left, startPoint.X); var actualWidth = this.ActualWidth; if (startPoint.X < monitorInfo.Work.Left) { actualWidth -= monitorInfo.Work.Left - startPoint.X; startPoint.X = monitorInfo.Work.Left; } // Set width and prevent negative values this.DropDownPopup.Width = Math.Max(0, Math.Min(actualWidth, inWindowRibbonWidth)); return(new[] { new CustomPopupPlacement(new Point(startPoint.X - tabItemPos.X, this.SelectedTabItem.ActualHeight - ((FrameworkElement)this.DropDownPopup.Child).Margin.Top), PopupPrimaryAxis.None), new CustomPopupPlacement(new Point(startPoint.X - tabItemPos.X, -((ScrollViewer)this.SelectedContent).ActualHeight - ((FrameworkElement)this.DropDownPopup.Child).Margin.Bottom), PopupPrimaryAxis.None) }); } } return(null); }
/// <summary> /// Implements custom placement for ribbon popup /// </summary> /// <param name="popupsize"></param> /// <param name="targetsize"></param> /// <param name="offset"></param> /// <returns></returns> CustomPopupPlacement[] CustomPopupPlacementMethod(Size popupsize, Size targetsize, Point offset) { if ((popup != null) && (SelectedTabItem != null)) { // Get current workarea Point tabItemPos = SelectedTabItem.PointToScreen(new Point(0, 0)); NativeMethods.Rect tabItemRect = new NativeMethods.Rect(); tabItemRect.Left = (int)tabItemPos.X; tabItemRect.Top = (int)tabItemPos.Y; tabItemRect.Right = (int)tabItemPos.X + (int)SelectedTabItem.ActualWidth; tabItemRect.Bottom = (int)tabItemPos.Y + (int)SelectedTabItem.ActualHeight; uint MONITOR_DEFAULTTONEAREST = 0x00000002; System.IntPtr monitor = NativeMethods.MonitorFromRect(ref tabItemRect, MONITOR_DEFAULTTONEAREST); if (monitor != System.IntPtr.Zero) { NativeMethods.MonitorInfo monitorInfo = new NativeMethods.MonitorInfo(); monitorInfo.Size = Marshal.SizeOf(monitorInfo); NativeMethods.GetMonitorInfo(monitor, monitorInfo); Point startPoint = PointToScreen(new Point(0, 0)); if (FlowDirection == FlowDirection.RightToLeft) { startPoint.X -= ActualWidth; } double inWindowRibbonWidth = monitorInfo.Work.Right - Math.Max(monitorInfo.Work.Left, startPoint.X); double actualWidth = ActualWidth; if (startPoint.X < monitorInfo.Work.Left) { actualWidth -= monitorInfo.Work.Left - startPoint.X; startPoint.X = monitorInfo.Work.Left; } // Set width popup.Width = Math.Min(actualWidth, inWindowRibbonWidth); return(new CustomPopupPlacement[] { new CustomPopupPlacement(new Point(startPoint.X - tabItemPos.X, SelectedTabItem.ActualHeight - (popup.Child as FrameworkElement).Margin.Top), PopupPrimaryAxis.None), new CustomPopupPlacement(new Point(startPoint.X - tabItemPos.X, -(SelectedContent as RibbonGroupsContainer).ActualHeight - (popup.Child as FrameworkElement).Margin.Bottom), PopupPrimaryAxis.None), }); } } return(null); }
/// <summary> /// Returns screen workarea in witch control is placed /// </summary> /// <param name="control">Control</param> /// <returns>Workarea in witch control is placed</returns> public static Rect GetControlWorkArea(FrameworkElement control) { var tabItemPos = control.PointToScreen(new Point(0, 0)); #pragma warning disable 618 var tabItemRect = new RECT { Left = (int)tabItemPos.X, Top = (int)tabItemPos.Y, Right = (int)tabItemPos.X + (int)control.ActualWidth, Bottom = (int)tabItemPos.Y + (int)control.ActualHeight }; var monitor = NativeMethods.MonitorFromRect(ref tabItemRect, MonitorOptions.MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { var monitorInfo = NativeMethods.GetMonitorInfo(monitor); return(new Rect(monitorInfo.rcWork.Left, monitorInfo.rcWork.Top, monitorInfo.rcWork.Right - monitorInfo.rcWork.Left, monitorInfo.rcWork.Bottom - monitorInfo.rcWork.Top)); } #pragma warning restore 618 return(default);
/// <summary> /// Returns screen workarea in witch control is placed /// </summary> /// <param name="control">Control</param> /// <returns>Workarea in witch control is placed</returns> public static Rect GetControlWorkArea(FrameworkElement control) { var tabItemPos = control.PointToScreen(new Point(0, 0)); var tabItemRect = new RECT(); tabItemRect.left = (int)tabItemPos.X; tabItemRect.top = (int)tabItemPos.Y; tabItemRect.right = (int)tabItemPos.X + (int)control.ActualWidth; tabItemRect.bottom = (int)tabItemPos.Y + (int)control.ActualHeight; var monitor = NativeMethods.MonitorFromRect(ref tabItemRect, MONITORINFO.MonitorOptions.MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { var monitorInfo = new MONITORINFO(); monitorInfo.cbSize = Marshal.SizeOf(monitorInfo); NativeMethods.GetMonitorInfo(monitor, monitorInfo); return(new Rect(monitorInfo.rcWork.left, monitorInfo.rcWork.top, monitorInfo.rcWork.right - monitorInfo.rcWork.left, monitorInfo.rcWork.bottom - monitorInfo.rcWork.top)); } return(new Rect()); }
/// <summary> /// Returns monitor in witch control is placed /// </summary> /// <param name="control">Control</param> /// <returns>Workarea in witch control is placed</returns> public static Rect GetControlMonitor(FrameworkElement control) { Point tabItemPos = control.PointToScreen(new Point(0, 0)); NativeMethods.Rect tabItemRect = new NativeMethods.Rect(); tabItemRect.Left = (int)tabItemPos.X; tabItemRect.Top = (int)tabItemPos.Y; tabItemRect.Right = (int)tabItemPos.X + (int)control.ActualWidth; tabItemRect.Bottom = (int)tabItemPos.Y + (int)control.ActualHeight; uint MONITOR_DEFAULTTONEAREST = 0x00000002; System.IntPtr monitor = NativeMethods.MonitorFromRect(ref tabItemRect, MONITOR_DEFAULTTONEAREST); if (monitor != System.IntPtr.Zero) { NativeMethods.MonitorInfo monitorInfo = new NativeMethods.MonitorInfo(); monitorInfo.Size = Marshal.SizeOf(monitorInfo); NativeMethods.GetMonitorInfo(monitor, monitorInfo); return(new Rect(monitorInfo.Monitor.Left, monitorInfo.Monitor.Top, monitorInfo.Monitor.Right - monitorInfo.Monitor.Left, monitorInfo.Monitor.Bottom - monitorInfo.Monitor.Top)); } return(new Rect()); }
/// <summary> /// Implements custom placement for ribbon popup /// </summary> private CustomPopupPlacement[] CustomPopupPlacementMethod(Size popupsize, Size targetsize, Point offset) { if (this.DropDownPopup == null || this.SelectedTabItem == null) { return(null); } var tabItemDimensionsOnScreen = this.SelectedTabItem.PointToScreen(new Point(this.SelectedTabItem.ActualWidth, this.SelectedTabItem.ActualHeight)) - this.SelectedTabItem.PointToScreen(new Point(0, 0)); var tabItemActualSizeOnScreen = new Point(Math.Abs(tabItemDimensionsOnScreen.X), Math.Abs(tabItemDimensionsOnScreen.Y)); var widthFactor = tabItemActualSizeOnScreen.X / this.SelectedTabItem.ActualWidth; var heightFactor = tabItemActualSizeOnScreen.Y / this.SelectedTabItem.ActualHeight; // Get current workarea var tabItemUpperLeftOnScreen = this.SelectedTabItem.PointToScreen(new Point(0, 0)); #pragma warning disable 618 var tabItemOriginPointOnScreenRect = new RECT { Left = (int)tabItemUpperLeftOnScreen.X, Top = (int)tabItemUpperLeftOnScreen.Y, Right = (int)tabItemUpperLeftOnScreen.X + (int)tabItemDimensionsOnScreen.X, Bottom = (int)tabItemUpperLeftOnScreen.Y + (int)tabItemDimensionsOnScreen.Y }; var monitor = NativeMethods.MonitorFromRect(ref tabItemOriginPointOnScreenRect, MonitorOptions.MONITOR_DEFAULTTONEAREST); if (monitor == IntPtr.Zero) { return(null); } var monitorInfo = NativeMethods.GetMonitorInfo(monitor); #pragma warning restore 618 var tabControlUpperLeftOnScreen = this.PointToScreen(new Point(0, 0)); var tabControlDimensionsOnScreen = this.PointToScreen(new Point(this.ActualWidth, this.ActualHeight)) - this.PointToScreen(new Point(0, 0)); var tabControlActualSizeOnScreen = new Point(Math.Abs(tabControlDimensionsOnScreen.X), Math.Abs(tabControlDimensionsOnScreen.Y)); if (this.FlowDirection == FlowDirection.RightToLeft) { tabControlUpperLeftOnScreen.X -= tabControlActualSizeOnScreen.X; } // Calculate the popup width // We have to take into account here that, when the window is moved to the side of a monitor and the window is not fully visible // the popup width is reduced to the maximum visible size of the window on the monitor the selected tab item is on. // If we don't reduce the popup width wpf tries to be helpful and moves the popup out of the window to satisfy the width. { var inWindowRibbonWidth = monitorInfo.rcWork.Right - Math.Max(monitorInfo.rcWork.Left, tabControlUpperLeftOnScreen.X); var actualWidth = this.ActualWidth; if (tabControlUpperLeftOnScreen.X < monitorInfo.rcWork.Left) { actualWidth -= (monitorInfo.rcWork.Left - tabControlUpperLeftOnScreen.X) / widthFactor; } // Set width and prevent negative values this.DropDownPopup.Width = Math.Max(0, Math.Min(actualWidth, inWindowRibbonWidth)); } return(new[] { new CustomPopupPlacement(new Point(tabControlUpperLeftOnScreen.X - tabItemUpperLeftOnScreen.X, tabItemActualSizeOnScreen.Y - (AdditionalPopupSpaceForKeyTips * heightFactor)), PopupPrimaryAxis.Vertical), new CustomPopupPlacement(new Point(tabControlUpperLeftOnScreen.X - tabItemUpperLeftOnScreen.X, -1 * (tabItemActualSizeOnScreen.Y - (AdditionalPopupSpaceForKeyTips * heightFactor))), PopupPrimaryAxis.Vertical) }); }