diff --git a/src/Shared/HandyControl_Shared/Controls/Other/Poptip.cs b/src/Shared/HandyControl_Shared/Controls/Other/Poptip.cs index 344e7a8f..c58607c6 100644 --- a/src/Shared/HandyControl_Shared/Controls/Other/Poptip.cs +++ b/src/Shared/HandyControl_Shared/Controls/Other/Poptip.cs @@ -4,8 +4,11 @@ using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Input; +using System.Windows.Threading; using HandyControl.Data; using HandyControl.Data.Enum; +using HandyControl.Expression.Drawing; +using HandyControl.Tools; namespace HandyControl.Controls; @@ -13,6 +16,8 @@ public class Poptip : AdornerElement { private readonly Popup _popup; + private DispatcherTimer _openTimer; + public Poptip() { _popup = new Popup @@ -172,6 +177,15 @@ public class Poptip : AdornerElement set => SetValue(IsOpenProperty, ValueBoxes.BooleanBox(value)); } + public static readonly DependencyProperty DelayProperty = DependencyProperty.Register( + "Delay", typeof(double), typeof(Poptip), new PropertyMetadata(1000.0), ValidateHelper.IsInRangeOfPosDoubleIncludeZero); + + public double Delay + { + get => (double) GetValue(DelayProperty); + set => SetValue(DelayProperty, value); + } + public static Poptip Default => new(); protected sealed override void OnTargetChanged(FrameworkElement element, bool isNew) @@ -290,8 +304,43 @@ public class Poptip : AdornerElement _popup.PlacementTarget = Target; UpdateLocation(); } - _popup.IsOpen = isShow; - Target.SetCurrentValue(IsOpenProperty, isShow); + + ResetTimer(); + + var delay = Delay; + if (!isShow || HitMode != HitMode.Hover || MathHelper.IsVerySmall(delay)) + { + + _popup.IsOpen = isShow; + Target.SetCurrentValue(IsOpenProperty, isShow); + } + else + { + _openTimer = new DispatcherTimer + { + Interval = TimeSpan.FromMilliseconds(delay) + }; + + _openTimer.Tick += OpenTimer_Tick; + _openTimer.Start(); + } + } + + private void ResetTimer() + { + if (_openTimer != null) + { + _openTimer.Stop(); + _openTimer = null; + } + } + + private void OpenTimer_Tick(object sender, EventArgs e) + { + _popup.IsOpen = true; + Target.SetCurrentValue(IsOpenProperty, true); + + ResetTimer(); } private void Element_MouseEnter(object sender, MouseEventArgs e) diff --git a/src/Shared/HandyControl_Shared/Controls/Ribbon/Ribbon.cs b/src/Shared/HandyControl_Shared/Controls/Ribbon/Ribbon.cs index 3a079210..59836c68 100644 --- a/src/Shared/HandyControl_Shared/Controls/Ribbon/Ribbon.cs +++ b/src/Shared/HandyControl_Shared/Controls/Ribbon/Ribbon.cs @@ -73,6 +73,11 @@ namespace HandyControl.Controls } var animation = isDropDownOpen ? CreateAnimation(0, ContentHeight) : CreateAnimation(ContentHeight, 0); + animation.Completed += (s, e) => + { + SwitchCurrentTabContentVisibility(isDropDownOpen); + }; + _contentPanel.BeginAnimation(HeightProperty, animation); } @@ -100,6 +105,7 @@ namespace HandyControl.Controls var animation = isMinimized ? CreateAnimation(_originHeight, _tabHeaderItemsControl.ActualHeight) : CreateAnimation(_tabHeaderItemsControl.ActualHeight, _originHeight); + _rootPanel.BeginAnimation(HeightProperty, animation); } @@ -331,6 +337,29 @@ namespace HandyControl.Controls return -1; } + private void SwitchCurrentTabContentVisibility(bool isVisible) + { + var tab = GetCurrentTab(); + tab?.SwitchContentVisibility(isVisible); + } + + private RibbonTab GetCurrentTab() + { + var index = SelectedIndex; + + if (index == -1) + { + return null; + } + + if (ItemContainerGenerator.ContainerFromIndex(index) is RibbonTab ribbonTab) + { + return ribbonTab; + } + + return null; + } + private void InitializeSelection() { if (!IsDropDownOpen) diff --git a/src/Shared/HandyControl_Shared/Controls/Ribbon/RibbonGroup.cs b/src/Shared/HandyControl_Shared/Controls/Ribbon/RibbonGroup.cs index e433c2a5..e19240ff 100644 --- a/src/Shared/HandyControl_Shared/Controls/Ribbon/RibbonGroup.cs +++ b/src/Shared/HandyControl_Shared/Controls/Ribbon/RibbonGroup.cs @@ -1,11 +1,23 @@ using System.Windows; using System.Windows.Controls; +using System.Windows.Input; using HandyControl.Data; +using HandyControl.Interactivity; namespace HandyControl.Controls { public class RibbonGroup : HeaderedItemsControl { + public RibbonGroup() + { + CommandBindings.Add(new CommandBinding(ControlCommands.More, LauncherButton_OnClick)); + } + + private void LauncherButton_OnClick(object sender, ExecutedRoutedEventArgs e) + { + OnLauncherClick(new RoutedEventArgs(LauncherClickEvent, this)); + } + public static readonly DependencyProperty ShowLauncherButtonProperty = DependencyProperty.Register( "ShowLauncherButton", typeof(bool), typeof(RibbonGroup), new PropertyMetadata(ValueBoxes.FalseBox)); @@ -23,5 +35,26 @@ namespace HandyControl.Controls get => (bool) GetValue(ShowSplitterProperty); set => SetValue(ShowSplitterProperty, value); } + + public static readonly DependencyProperty LauncherPoptipProperty = DependencyProperty.Register( + "LauncherPoptip", typeof(Poptip), typeof(RibbonGroup), new PropertyMetadata(default(Poptip))); + + public Poptip LauncherPoptip + { + get => (Poptip) GetValue(LauncherPoptipProperty); + set => SetValue(LauncherPoptipProperty, value); + } + + public static readonly RoutedEvent LauncherClickEvent = + EventManager.RegisterRoutedEvent("LauncherClick", RoutingStrategy.Bubble, + typeof(RoutedEventHandler), typeof(RibbonGroup)); + + public event RoutedEventHandler LauncherClick + { + add => AddHandler(LauncherClickEvent, value); + remove => RemoveHandler(LauncherClickEvent, value); + } + + protected virtual void OnLauncherClick(RoutedEventArgs e) => RaiseEvent(e); } } diff --git a/src/Shared/HandyControl_Shared/Controls/Ribbon/RibbonTab.cs b/src/Shared/HandyControl_Shared/Controls/Ribbon/RibbonTab.cs index e9db9547..57273429 100644 --- a/src/Shared/HandyControl_Shared/Controls/Ribbon/RibbonTab.cs +++ b/src/Shared/HandyControl_Shared/Controls/Ribbon/RibbonTab.cs @@ -2,11 +2,17 @@ using System.Windows.Controls; using System.Windows.Controls.Primitives; using HandyControl.Data; +using HandyControl.Tools.Extension; namespace HandyControl.Controls { + [TemplatePart(Name = RootContainer, Type = typeof(UIElement))] public class RibbonTab : HeaderedItemsControl { + private const string RootContainer = "PART_RootContainer"; + + private UIElement _rootContainer; + public Ribbon Ribbon => Ribbon.GetRibbon(this); internal RibbonTabHeader RibbonTabHeader @@ -48,10 +54,16 @@ namespace HandyControl.Controls var ribbonTab = (RibbonTab) d; if (ribbonTab.IsSelected) { + if (ribbonTab.Ribbon.IsDropDownOpen) + { + ribbonTab.SwitchContentVisibility(true); + } + ribbonTab.OnSelected(new RoutedEventArgs(Selector.SelectedEvent, ribbonTab)); } else { + ribbonTab.SwitchContentVisibility(false); ribbonTab.OnUnselected(new RoutedEventArgs(Selector.UnselectedEvent, ribbonTab)); } @@ -64,6 +76,16 @@ namespace HandyControl.Controls set => SetValue(IsSelectedProperty, value); } + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + _rootContainer = GetTemplateChild(RootContainer) as UIElement; + + SwitchContentVisibility(IsSelected); + } + + internal void SwitchContentVisibility(bool isVisible) => _rootContainer?.Show(isVisible); + protected virtual void OnSelected(RoutedEventArgs e) => RaiseEvent(e); protected virtual void OnUnselected(RoutedEventArgs e) => RaiseEvent(e); diff --git a/src/Shared/HandyControl_Shared/Data/ValueBoxes.cs b/src/Shared/HandyControl_Shared/Data/ValueBoxes.cs index 800ae300..28f747c2 100644 --- a/src/Shared/HandyControl_Shared/Data/ValueBoxes.cs +++ b/src/Shared/HandyControl_Shared/Data/ValueBoxes.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Windows; using System.Windows.Controls; @@ -23,8 +23,6 @@ internal static class ValueBoxes internal static object HiddenBox = Visibility.Hidden; - internal static object Double0Box = .0; - internal static object Double01Box = .1; internal static object Double0Box = .0; diff --git a/src/Shared/HandyControl_Shared/Interactivity/Commands/ControlCommands.cs b/src/Shared/HandyControl_Shared/Interactivity/Commands/ControlCommands.cs index bea450e0..8a03934f 100644 --- a/src/Shared/HandyControl_Shared/Interactivity/Commands/ControlCommands.cs +++ b/src/Shared/HandyControl_Shared/Interactivity/Commands/ControlCommands.cs @@ -181,4 +181,9 @@ public static class ControlCommands /// 按照名称排序 /// public static RoutedCommand SortByName { get; } = new(nameof(SortByName), typeof(ControlCommands)); + + /// + /// 更多 + /// + public static RoutedCommand More { get; } = new(nameof(More), typeof(ControlCommands)); } diff --git a/src/Shared/HandyControl_Shared/Themes/Styles/Ribbon.xaml b/src/Shared/HandyControl_Shared/Themes/Styles/Ribbon.xaml index 9a3ea6e6..b8f09c26 100644 --- a/src/Shared/HandyControl_Shared/Themes/Styles/Ribbon.xaml +++ b/src/Shared/HandyControl_Shared/Themes/Styles/Ribbon.xaml @@ -4,7 +4,7 @@ xmlns:interactivity="clr-namespace:HandyControl.Interactivity" xmlns:system="clr-namespace:System;assembly=mscorlib"> - M878.3 392.1L631.9 145.7c-6.5-6.5-15-9.7-23.5-9.7s-17 3.2-23.5 9.7L423.8 306.9c-12.2-1.4-24.5-2-36.8-2-73.2 0-146.4 24.1-206.5 72.3-15.4 12.3-16.6 35.4-2.7 49.4l181.7 181.7-215.4 215.2c-2.6 2.6-4.3 6.1-4.6 9.8l-3.4 37.2c-0.9 9.4 6.6 17.4 15.9 17.4 0.5 0 1 0 1.5-0.1l37.2-3.4c3.7-0.3 7.2-2 9.8-4.6l215.4-215.4 181.7 181.7c6.5 6.5 15 9.7 23.5 9.7 9.7 0 19.3-4.2 25.9-12.4 56.3-70.3 79.7-158.3 70.2-243.4l161.1-161.1c12.9-12.8 12.9-33.8 0-46.8z + M956.553 366.486L657.514 67.447c-7.888-7.888-18.204-11.772-28.52-11.772s-20.632 3.884-28.52 11.772L404.958 263.085c-14.806-1.7-29.734-2.428-44.662-2.428-88.837 0-177.675 29.249-250.614 87.746-18.69 14.927-20.268 42.962-3.277 59.953l220.516 220.517L65.506 890.046c-3.156 3.155-5.219 7.403-5.583 11.893l-4.126 45.147c-1.093 11.408 8.01 21.117 19.296 21.117 0.607 0 1.214 0 1.82-0.121l45.148-4.126c4.49-0.364 8.738-2.428 11.893-5.583L395.37 696.957l220.517 220.517c7.888 7.888 18.204 11.772 28.52 11.772 11.772 0 23.423-5.097 31.433-15.05 68.327-85.317 96.726-192.117 85.197-295.397l195.516-195.515c15.655-15.535 15.655-41.021 0-56.798zM699.142 557.268l-29.734 29.734 4.612 41.75c4.49 40.898 1.213 81.555-9.952 120.998-6.554 23.059-15.535 45.026-26.943 65.779L208.593 386.753c15.655-8.616 31.918-15.898 48.909-21.724 33.01-11.408 67.599-17.112 102.794-17.112 11.651 0 23.423 0.607 35.074 1.942l41.75 4.612 29.733-29.734 162.262-162.262 232.41 232.41-162.383 162.383z M0,0 8,0 8,1 1,1 1,8 0,8 M 3.7,3 8,7.3 8,4 9,4 9,9 4,9 4,8 7.3,8 3,3.7