123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- using System;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Controls.Primitives;
- using HandyControl.Tools;
- namespace HandyControl.Controls;
- public class MenuTopLineAttach
- {
- public static readonly DependencyProperty PopupProperty = DependencyProperty.RegisterAttached(
- "Popup", typeof(Popup), typeof(MenuTopLineAttach), new PropertyMetadata(default(Popup), OnPopupChanged));
- private static void OnPopupChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var topLine = (FrameworkElement) d;
- if (e.NewValue is Popup { TemplatedParent: MenuItem menuItem })
- {
- SetTopLine(menuItem, topLine);
- menuItem.Loaded += MenuItem_Loaded;
- }
- }
- private static void MenuItem_Loaded(object sender, RoutedEventArgs e)
- {
- var menuItem = (FrameworkElement) sender;
- menuItem.Unloaded += MenuItem_Unloaded;
- var topLine = GetTopLine(menuItem);
- var popup = GetPopup(topLine);
- if (popup != null)
- {
- popup.Opened += Popup_Opened;
- }
- }
- private static void MenuItem_Unloaded(object sender, RoutedEventArgs e)
- {
- var menuItem = (FrameworkElement) sender;
- menuItem.Unloaded -= MenuItem_Unloaded;
- var topLine = GetTopLine(menuItem);
- var popup = GetPopup(topLine);
- if (popup != null)
- {
- popup.Opened -= Popup_Opened;
- }
- }
- private static void Popup_Opened(object sender, EventArgs e)
- {
- var popup = (Popup) sender;
- if (popup.TemplatedParent is MenuItem menuItem)
- {
- var topLine = GetTopLine(menuItem);
- if (topLine == null) return;
- topLine.HorizontalAlignment = HorizontalAlignment.Left;
- topLine.Width = menuItem.ActualWidth;
- topLine.Margin = new Thickness();
- var positionLeftTop = menuItem.PointToScreen(new Point());
- var positionRightBottom = menuItem.PointToScreen(new Point(menuItem.ActualWidth, menuItem.ActualHeight));
- ScreenHelper.FindMonitorRectsFromPoint(positionLeftTop, out _, out var workAreaRect);
- var panel = VisualHelper.GetParent<Panel>(topLine);
- if (positionLeftTop.X < 0)
- {
- topLine.Margin = new Thickness(positionLeftTop.X - panel.Margin.Left, 0, 0, 0);
- }
- else if (positionLeftTop.X + panel.ActualWidth > workAreaRect.Right)
- {
- var overflowWidth = positionRightBottom.X - workAreaRect.Right;
- if (overflowWidth > 0)
- {
- topLine.Width -= overflowWidth + panel.Margin.Right;
- }
- topLine.HorizontalAlignment = HorizontalAlignment.Left;
- topLine.Margin = new Thickness(positionLeftTop.X + panel.ActualWidth - workAreaRect.Right + panel.Margin.Right, 0, 0, 0);
- }
- if (positionRightBottom.Y > workAreaRect.Bottom)
- {
- topLine.Width = 0;
- topLine.HorizontalAlignment = HorizontalAlignment.Stretch;
- topLine.Margin = new Thickness();
- }
- }
- }
- public static void SetPopup(DependencyObject element, Popup value)
- => element.SetValue(PopupProperty, value);
- public static Popup GetPopup(DependencyObject element)
- => (Popup) element.GetValue(PopupProperty);
- internal static readonly DependencyProperty TopLineProperty = DependencyProperty.RegisterAttached(
- "TopLine", typeof(FrameworkElement), typeof(MenuTopLineAttach), new PropertyMetadata(default(FrameworkElement)));
- internal static void SetTopLine(DependencyObject element, FrameworkElement value)
- => element.SetValue(TopLineProperty, value);
- internal static FrameworkElement GetTopLine(DependencyObject element)
- => (FrameworkElement) element.GetValue(TopLineProperty);
- }
|