diff --git a/HandyControl/Controls/Other/GotoTop.cs b/HandyControl/Controls/Other/GotoTop.cs new file mode 100644 index 00000000..199da8c7 --- /dev/null +++ b/HandyControl/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.ScrollToVerticalOffsetInternal(0, 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/HandyControl/HandyControl.csproj b/HandyControl/HandyControl.csproj index 0b3cdcc7..efbf174e 100644 --- a/HandyControl/HandyControl.csproj +++ b/HandyControl/HandyControl.csproj @@ -111,6 +111,7 @@ + @@ -379,6 +380,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -427,6 +432,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/HandyControl/Themes/Styles/Base/GotoTopBaseStyle.xaml b/HandyControl/Themes/Styles/Base/GotoTopBaseStyle.xaml new file mode 100644 index 00000000..5c90ba29 --- /dev/null +++ b/HandyControl/Themes/Styles/Base/GotoTopBaseStyle.xaml @@ -0,0 +1,28 @@ + + + + + + + + + + \ No newline at end of file diff --git a/HandyControl/Themes/Styles/GotoTop.xaml b/HandyControl/Themes/Styles/GotoTop.xaml new file mode 100644 index 00000000..ebe37f33 --- /dev/null +++ b/HandyControl/Themes/Styles/GotoTop.xaml @@ -0,0 +1,10 @@ + + + + + + +