From 82f69264160ddc087e90c6b3458412c05f56e219 Mon Sep 17 00:00:00 2001
From: NaBian <836904362@qq.com>
Date: Sun, 8 Aug 2021 16:17:05 +0800
Subject: [PATCH] RibbonGroup support for LauncherButton
---
.../Controls/Other/Poptip.cs | 53 ++++++++++++++++++-
.../Controls/Ribbon/Ribbon.cs | 29 ++++++++++
.../Controls/Ribbon/RibbonGroup.cs | 33 ++++++++++++
.../Controls/Ribbon/RibbonTab.cs | 22 ++++++++
.../HandyControl_Shared/Data/ValueBoxes.cs | 4 +-
.../Interactivity/Commands/ControlCommands.cs | 5 ++
.../Themes/Styles/Ribbon.xaml | 10 ++--
7 files changed, 146 insertions(+), 10 deletions(-)
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