diff --git a/src/Net_40/HandyControl_Net_40/Themes/Theme.xaml b/src/Net_40/HandyControl_Net_40/Themes/Theme.xaml
index 0ca52e76..c7b03f62 100644
--- a/src/Net_40/HandyControl_Net_40/Themes/Theme.xaml
+++ b/src/Net_40/HandyControl_Net_40/Themes/Theme.xaml
@@ -832,6 +832,31 @@
+ 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
+
@@ -7056,16 +7081,18 @@
-
-
+
+
+
@@ -10867,7 +10894,7 @@
-
+
@@ -13335,6 +13362,132 @@
+
+
+
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/Panel/ClipGrid.cs b/src/Shared/HandyControl_Shared/Controls/Panel/ClipGrid.cs
new file mode 100644
index 00000000..7ddcd61a
--- /dev/null
+++ b/src/Shared/HandyControl_Shared/Controls/Panel/ClipGrid.cs
@@ -0,0 +1,29 @@
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using HandyControl.Data;
+
+namespace HandyControl.Controls
+{
+ public class ClipGrid : Grid
+ {
+ public static readonly DependencyProperty IsClipEnabledProperty = DependencyProperty.Register(
+ "IsClipEnabled", typeof(bool), typeof(ClipGrid), new PropertyMetadata(ValueBoxes.TrueBox));
+
+ public bool IsClipEnabled
+ {
+ get => (bool) GetValue(IsClipEnabledProperty);
+ set => SetValue(IsClipEnabledProperty, ValueBoxes.BooleanBox(value));
+ }
+
+ protected override Geometry GetLayoutClip(Size layoutSlotSize)
+ {
+ if (IsClipEnabled)
+ {
+ return base.GetLayoutClip(layoutSlotSize);
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/Shared/HandyControl_Shared/Controls/Ribbon/Ribbon.cs b/src/Shared/HandyControl_Shared/Controls/Ribbon/Ribbon.cs
new file mode 100644
index 00000000..a46aab5f
--- /dev/null
+++ b/src/Shared/HandyControl_Shared/Controls/Ribbon/Ribbon.cs
@@ -0,0 +1,408 @@
+// some code fetch from system.windows.controls.ribbon.
+
+using System;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Input;
+using HandyControl.Data;
+using HandyControl.Interactivity;
+using HandyControl.Tools.Extension;
+
+namespace HandyControl.Controls
+{
+ // TODO: this control is a work-in-progress, it needs to support things like automatic resizing.
+ [TemplatePart(Name = TabHeaderItemsControl, Type = typeof(ItemsControl))]
+ [TemplatePart(Name = RootPanel, Type = typeof(Panel))]
+ [TemplatePart(Name = ContentPanel, Type = typeof(Panel))]
+ public class Ribbon : Selector
+ {
+ private const string TabHeaderItemsControl = "PART_TabHeaderItemsControl";
+
+ private const string RootPanel = "PART_RootPanel";
+
+ private const string ContentPanel = "PART_ContentPanel";
+
+ private ItemsControl _tabHeaderItemsControl;
+
+ private Panel _rootPanel;
+
+ private Panel _contentPanel;
+
+ private System.Windows.Window _window;
+
+ private readonly ObservableCollection