diff --git a/HandyControl/Controls/Other/GotoTop.cs b/HandyControl/Controls/Other/GotoTop.cs
index 199da8c7..62d004a3 100644
--- a/HandyControl/Controls/Other/GotoTop.cs
+++ b/HandyControl/Controls/Other/GotoTop.cs
@@ -37,7 +37,7 @@ namespace HandyControl.Controls
if (_scrollViewer is ScrollViewer scrollViewerHandy && Animated && scrollViewerHandy.IsEnableInertia)
{
- _gotoTopAction = () => scrollViewerHandy.ScrollToVerticalOffsetInternal(0, AnimationTime);
+ _gotoTopAction = () => scrollViewerHandy.ScrollToTopInternal(AnimationTime);
}
else
{
diff --git a/HandyControl/Controls/Other/ScrollViewer.cs b/HandyControl/Controls/Other/ScrollViewer.cs
index 823e66fc..533afbb6 100644
--- a/HandyControl/Controls/Other/ScrollViewer.cs
+++ b/HandyControl/Controls/Other/ScrollViewer.cs
@@ -90,6 +90,16 @@ namespace HandyControl.Controls
}
}
+ internal void ScrollToTopInternal(double milliseconds = 500)
+ {
+ if (!_isRunning)
+ {
+ _totalVerticalOffset = VerticalOffset;
+ CurrentVerticalOffset = VerticalOffset;
+ }
+ ScrollToVerticalOffsetInternal(0, milliseconds);
+ }
+
internal void ScrollToVerticalOffsetInternal(double offset, double milliseconds = 500)
{
var animation = AnimationHelper.CreateAnimation(offset, milliseconds);
diff --git a/HandyControl/Tools/Helper/VisualHelper.cs b/HandyControl/Tools/Helper/VisualHelper.cs
index e49effc2..77b127a8 100644
--- a/HandyControl/Tools/Helper/VisualHelper.cs
+++ b/HandyControl/Tools/Helper/VisualHelper.cs
@@ -1,6 +1,5 @@
using System.Linq;
using System.Windows;
-using System.Windows.Controls;
using System.Windows.Media;
namespace HandyControl.Tools
diff --git a/HandyControlDemo/UserControl/Controls/GotoTopDemoCtl.xaml b/HandyControlDemo/UserControl/Controls/GotoTopDemoCtl.xaml
index 78bd91cd..87c61e84 100644
--- a/HandyControlDemo/UserControl/Controls/GotoTopDemoCtl.xaml
+++ b/HandyControlDemo/UserControl/Controls/GotoTopDemoCtl.xaml
@@ -3,17 +3,19 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl"
Background="{DynamicResource RegionBrush}">
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Net40/HandyControlDemo_Net40/Data/MessageToken.cs b/Net40/HandyControlDemo_Net40/Data/MessageToken.cs
index c65216bd..e63c9770 100644
--- a/Net40/HandyControlDemo_Net40/Data/MessageToken.cs
+++ b/Net40/HandyControlDemo_Net40/Data/MessageToken.cs
@@ -82,6 +82,8 @@
public static readonly string ChatBubbleDemoCtl = nameof(ChatBubbleDemoCtl);
+ public static readonly string GotoTopDemoCtl = nameof(GotoTopDemoCtl);
+
public static readonly string ButtonDemoCtl = nameof(ButtonDemoCtl);
public static readonly string ToggleButtonDemoCtl = nameof(ToggleButtonDemoCtl);
diff --git a/Net40/HandyControlDemo_Net40/Data/MessageToken.tt b/Net40/HandyControlDemo_Net40/Data/MessageToken.tt
index 8c10a656..377d9b64 100644
--- a/Net40/HandyControlDemo_Net40/Data/MessageToken.tt
+++ b/Net40/HandyControlDemo_Net40/Data/MessageToken.tt
@@ -43,7 +43,8 @@ var controlList = new List
"CoverFlowDemoCtl",
"ProgressButtonDemoCtl",
"TransferDemoCtl",
- "ChatBubbleDemoCtl"
+ "ChatBubbleDemoCtl",
+ "GotoTopDemoCtl"
};
var styleList = new List
{
diff --git a/Net40/HandyControlDemo_Net40/HandyControlDemo_Net40.csproj b/Net40/HandyControlDemo_Net40/HandyControlDemo_Net40.csproj
index 326d0fa0..9eb92b9a 100644
--- a/Net40/HandyControlDemo_Net40/HandyControlDemo_Net40.csproj
+++ b/Net40/HandyControlDemo_Net40/HandyControlDemo_Net40.csproj
@@ -154,6 +154,9 @@
FlipClockDemoCtl.xaml
+
+ GotoTopDemoCtl.xaml
+
OutlineTextDemoCtl.xaml
@@ -467,6 +470,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
@@ -725,6 +732,7 @@
TextTemplatingFileGenerator
MessageToken.cs
+
diff --git a/Net40/HandyControlDemo_Net40/Properties/Langs/Lang.Designer.cs b/Net40/HandyControlDemo_Net40/Properties/Langs/Lang.Designer.cs
index a4e7d112..cddf738d 100644
--- a/Net40/HandyControlDemo_Net40/Properties/Langs/Lang.Designer.cs
+++ b/Net40/HandyControlDemo_Net40/Properties/Langs/Lang.Designer.cs
@@ -47,7 +47,7 @@ namespace HandyControlDemo.Properties.Langs {
}
///
- /// 重写当前线程的 CurrentUICulture 属性
+ /// 使用此强类型资源类,为所有资源查找
/// 重写当前线程的 CurrentUICulture 属性。
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
@@ -438,6 +438,15 @@ namespace HandyControlDemo.Properties.Langs {
}
}
+ ///
+ /// 查找类似 回到顶部 的本地化字符串。
+ ///
+ public static string GotoTop {
+ get {
+ return ResourceManager.GetString("GotoTop", resourceCulture);
+ }
+ }
+
///
/// 查找类似 分组框 的本地化字符串。
///
diff --git a/Net40/HandyControlDemo_Net40/Properties/Langs/Lang.en.resx b/Net40/HandyControlDemo_Net40/Properties/Langs/Lang.en.resx
index 3ea49fc7..3f57a795 100644
--- a/Net40/HandyControlDemo_Net40/Properties/Langs/Lang.en.resx
+++ b/Net40/HandyControlDemo_Net40/Properties/Langs/Lang.en.resx
@@ -498,4 +498,7 @@
Label
+
+ GotoTop
+
\ No newline at end of file
diff --git a/Net40/HandyControlDemo_Net40/Properties/Langs/Lang.resx b/Net40/HandyControlDemo_Net40/Properties/Langs/Lang.resx
index 0b8bdbc9..32ab263a 100644
--- a/Net40/HandyControlDemo_Net40/Properties/Langs/Lang.resx
+++ b/Net40/HandyControlDemo_Net40/Properties/Langs/Lang.resx
@@ -498,4 +498,7 @@
标签
+
+ 回到顶部
+
\ No newline at end of file
diff --git a/Net40/HandyControlDemo_Net40/Resources/Img/LeftMainContent/GoToTop_16x.png b/Net40/HandyControlDemo_Net40/Resources/Img/LeftMainContent/GoToTop_16x.png
new file mode 100644
index 00000000..2b3d22a9
Binary files /dev/null and b/Net40/HandyControlDemo_Net40/Resources/Img/LeftMainContent/GoToTop_16x.png differ
diff --git a/Net40/HandyControlDemo_Net40/UserControl/Controls/GotoTopDemoCtl.xaml b/Net40/HandyControlDemo_Net40/UserControl/Controls/GotoTopDemoCtl.xaml
new file mode 100644
index 00000000..548dcf15
--- /dev/null
+++ b/Net40/HandyControlDemo_Net40/UserControl/Controls/GotoTopDemoCtl.xaml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Net40/HandyControlDemo_Net40/UserControl/Controls/GotoTopDemoCtl.xaml.cs b/Net40/HandyControlDemo_Net40/UserControl/Controls/GotoTopDemoCtl.xaml.cs
new file mode 100644
index 00000000..3626a1df
--- /dev/null
+++ b/Net40/HandyControlDemo_Net40/UserControl/Controls/GotoTopDemoCtl.xaml.cs
@@ -0,0 +1,10 @@
+namespace HandyControlDemo.UserControl
+{
+ public partial class GotoTopDemoCtl
+ {
+ public GotoTopDemoCtl()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Net40/HandyControlDemo_Net40/UserControl/Main/LeftMainContent.xaml b/Net40/HandyControlDemo_Net40/UserControl/Main/LeftMainContent.xaml
index eb776ae3..536ce1bc 100644
--- a/Net40/HandyControlDemo_Net40/UserControl/Main/LeftMainContent.xaml
+++ b/Net40/HandyControlDemo_Net40/UserControl/Main/LeftMainContent.xaml
@@ -187,6 +187,11 @@
+
+
+
+
+
@@ -292,7 +297,7 @@
-
+
diff --git a/Net40/HandyControl_Net40/Controls/Other/GotoTop.cs b/Net40/HandyControl_Net40/Controls/Other/GotoTop.cs
new file mode 100644
index 00000000..0c16317e
--- /dev/null
+++ b/Net40/HandyControl_Net40/Controls/Other/GotoTop.cs
@@ -0,0 +1,100 @@
+using System;
+using System.Windows;
+using System.Windows.Controls;
+using HandyControl.Data;
+using HandyControl.Tools;
+using HandyControl.Tools.Extension;
+
+namespace HandyControl.Controls
+{
+ public class GotoTop : Button
+ {
+ private Action _gotoTopAction;
+
+ private System.Windows.Controls.ScrollViewer _scrollViewer;
+
+ public static readonly DependencyProperty TargetProperty = DependencyProperty.Register(
+ "Target", typeof(DependencyObject), typeof(GotoTop), new PropertyMetadata(default(DependencyObject)));
+
+ public DependencyObject Target
+ {
+ get => (DependencyObject)GetValue(TargetProperty);
+ set => SetValue(TargetProperty, value);
+ }
+
+ public GotoTop() => Loaded += (s, e) => CreateGotoAction(Target);
+
+ public virtual void CreateGotoAction(DependencyObject obj)
+ {
+ if (_scrollViewer != null)
+ {
+ _scrollViewer.ScrollChanged -= ScrollViewer_ScrollChanged;
+ }
+ _scrollViewer = VisualHelper.GetGetChild(obj);
+ if (_scrollViewer != null)
+ {
+ _scrollViewer.ScrollChanged += ScrollViewer_ScrollChanged;
+
+ if (_scrollViewer is ScrollViewer scrollViewerHandy && Animated && scrollViewerHandy.IsEnableInertia)
+ {
+ _gotoTopAction = () => scrollViewerHandy.ScrollToTopInternal(AnimationTime);
+ }
+ else
+ {
+ _gotoTopAction = () => _scrollViewer.ScrollToTop();
+ }
+ }
+ }
+
+ private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
+ {
+ if (AutoHiding)
+ {
+ this.Show(e.VerticalOffset >= HidingHeight);
+ }
+ }
+
+ public static readonly DependencyProperty AnimatedProperty = DependencyProperty.Register(
+ "Animated", typeof(bool), typeof(GotoTop), new PropertyMetadata(ValueBoxes.TrueBox));
+
+ public bool Animated
+ {
+ get => (bool)GetValue(AnimatedProperty);
+ set => SetValue(AnimatedProperty, value);
+ }
+
+ public static readonly DependencyProperty AnimationTimeProperty = DependencyProperty.Register(
+ "AnimationTime", typeof(double), typeof(GotoTop), new PropertyMetadata(ValueBoxes.Double200Box));
+
+ public double AnimationTime
+ {
+ get => (double)GetValue(AnimationTimeProperty);
+ set => SetValue(AnimationTimeProperty, value);
+ }
+
+ public static readonly DependencyProperty HidingHeightProperty = DependencyProperty.Register(
+ "HidingHeight", typeof(double), typeof(GotoTop), new PropertyMetadata(default(double)));
+
+ public double HidingHeight
+ {
+ get => (double)GetValue(HidingHeightProperty);
+ set => SetValue(HidingHeightProperty, value);
+ }
+
+ public static readonly DependencyProperty AutoHidingProperty = DependencyProperty.Register(
+ "AutoHiding", typeof(bool), typeof(GotoTop), new PropertyMetadata(ValueBoxes.TrueBox));
+
+ public bool AutoHiding
+ {
+ get => (bool)GetValue(AutoHidingProperty);
+ set => SetValue(AutoHidingProperty, value);
+ }
+
+ protected override void OnClick()
+ {
+ base.OnClick();
+
+ _gotoTopAction?.Invoke();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Net40/HandyControl_Net40/Controls/Other/ScrollViewer.cs b/Net40/HandyControl_Net40/Controls/Other/ScrollViewer.cs
index 823e66fc..f31297f8 100644
--- a/Net40/HandyControl_Net40/Controls/Other/ScrollViewer.cs
+++ b/Net40/HandyControl_Net40/Controls/Other/ScrollViewer.cs
@@ -28,7 +28,7 @@ namespace HandyControl.Controls
///
public Orientation Orientation
{
- get => (Orientation) GetValue(OrientationProperty);
+ get => (Orientation)GetValue(OrientationProperty);
set => SetValue(OrientationProperty, value);
}
@@ -43,7 +43,7 @@ namespace HandyControl.Controls
///
public bool CanMouseWheel
{
- get => (bool) GetValue(CanMouseWheelProperty);
+ get => (bool)GetValue(CanMouseWheelProperty);
set => SetValue(CanMouseWheelProperty, value);
}
@@ -90,6 +90,16 @@ namespace HandyControl.Controls
}
}
+ internal void ScrollToTopInternal(double milliseconds = 500)
+ {
+ if (!_isRunning)
+ {
+ _totalVerticalOffset = VerticalOffset;
+ CurrentVerticalOffset = VerticalOffset;
+ }
+ ScrollToVerticalOffsetInternal(0, milliseconds);
+ }
+
internal void ScrollToVerticalOffsetInternal(double offset, double milliseconds = 500)
{
var animation = AnimationHelper.CreateAnimation(offset, milliseconds);
@@ -140,7 +150,7 @@ namespace HandyControl.Controls
public static bool GetIsEnableInertia(DependencyObject element)
{
- return (bool) element.GetValue(IsEnableInertiaProperty);
+ return (bool)element.GetValue(IsEnableInertiaProperty);
}
///
@@ -174,7 +184,7 @@ namespace HandyControl.Controls
public static bool GetIsPenetrating(DependencyObject element)
{
- return (bool) element.GetValue(IsPenetratingProperty);
+ return (bool)element.GetValue(IsPenetratingProperty);
}
///
@@ -197,7 +207,7 @@ namespace HandyControl.Controls
private double CurrentVerticalOffset
{
// ReSharper disable once UnusedMember.Local
- get => (double) GetValue(CurrentVerticalOffsetProperty);
+ get => (double)GetValue(CurrentVerticalOffsetProperty);
set => SetValue(CurrentVerticalOffsetProperty, value);
}
@@ -220,7 +230,7 @@ namespace HandyControl.Controls
///
public double CurrentHorizontalOffset
{
- get => (double) GetValue(CurrentHorizontalOffsetProperty);
+ get => (double)GetValue(CurrentHorizontalOffsetProperty);
set => SetValue(CurrentHorizontalOffsetProperty, value);
}
}
diff --git a/Net40/HandyControl_Net40/HandyControl_Net40.csproj b/Net40/HandyControl_Net40/HandyControl_Net40.csproj
index a1d47132..5896f9a7 100644
--- a/Net40/HandyControl_Net40/HandyControl_Net40.csproj
+++ b/Net40/HandyControl_Net40/HandyControl_Net40.csproj
@@ -65,6 +65,7 @@
+
@@ -333,6 +334,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
@@ -381,6 +386,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
diff --git a/Net40/HandyControl_Net40/Themes/Styles/Base/GotoTopBaseStyle.xaml b/Net40/HandyControl_Net40/Themes/Styles/Base/GotoTopBaseStyle.xaml
new file mode 100644
index 00000000..10729b2a
--- /dev/null
+++ b/Net40/HandyControl_Net40/Themes/Styles/Base/GotoTopBaseStyle.xaml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Net40/HandyControl_Net40/Themes/Styles/GotoTop.xaml b/Net40/HandyControl_Net40/Themes/Styles/GotoTop.xaml
new file mode 100644
index 00000000..8af2d097
--- /dev/null
+++ b/Net40/HandyControl_Net40/Themes/Styles/GotoTop.xaml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Net40/HandyControl_Net40/Themes/Styles/Style.xaml b/Net40/HandyControl_Net40/Themes/Styles/Style.xaml
index 4c60d443..dfc27adc 100644
--- a/Net40/HandyControl_Net40/Themes/Styles/Style.xaml
+++ b/Net40/HandyControl_Net40/Themes/Styles/Style.xaml
@@ -57,6 +57,7 @@
+
\ No newline at end of file
diff --git a/Net40/HandyControl_Net40/Tools/Helper/VisualHelper.cs b/Net40/HandyControl_Net40/Tools/Helper/VisualHelper.cs
index 115a74c8..77b127a8 100644
--- a/Net40/HandyControl_Net40/Tools/Helper/VisualHelper.cs
+++ b/Net40/HandyControl_Net40/Tools/Helper/VisualHelper.cs
@@ -6,9 +6,9 @@ namespace HandyControl.Tools
{
public class VisualHelper
{
- internal static VisualStateGroup TryGetVisualStateGroup(DependencyObject dependencyObject, string groupName)
+ internal static VisualStateGroup TryGetVisualStateGroup(DependencyObject d, string groupName)
{
- var root = GetImplementationRoot(dependencyObject);
+ var root = GetImplementationRoot(d);
if (root == null)
{
return null;
@@ -20,13 +20,35 @@ namespace HandyControl.Tools
.FirstOrDefault(group => string.CompareOrdinal(groupName, group.Name) == 0);
}
- internal static FrameworkElement GetImplementationRoot(DependencyObject dependencyObject)
+ internal static FrameworkElement GetImplementationRoot(DependencyObject d)
{
- return 1 == VisualTreeHelper.GetChildrenCount(dependencyObject)
- ? VisualTreeHelper.GetChild(dependencyObject, 0) as FrameworkElement
+ return 1 == VisualTreeHelper.GetChildrenCount(d)
+ ? VisualTreeHelper.GetChild(d, 0) as FrameworkElement
: null;
}
+ internal static T GetGetChild(DependencyObject d) where T : DependencyObject
+ {
+ if (d is T scrollViewer)
+ {
+ return scrollViewer;
+ }
+
+ for (int i = 0; i < VisualTreeHelper.GetChildrenCount(d); i++)
+ {
+ var child = VisualTreeHelper.GetChild(d, i);
+
+ var result = GetGetChild(child);
+ if (result != null) return result;
+ }
+
+ return default(T);
+ }
+
+ ///
+ /// 获取当前应用中处于激活的一个窗口
+ ///
+ ///
public static Window GetActiveWindow() => Application.Current.Windows.OfType().SingleOrDefault(x => x.IsActive);
}
}
\ No newline at end of file