From ef1d436173e55b6612b676c28cd04eb097b9317f Mon Sep 17 00:00:00 2001 From: SlimeNull Date: Mon, 15 Jul 2024 18:27:34 +0800 Subject: [PATCH 1/7] Optimize the scrolling experience --- Directory.Packages.props | 1 + ILSpy/App.xaml | 52 +++-- ILSpy/Controls/ZoomScrollViewer.cs | 2 +- ILSpy/ILSpy.csproj | 1 + ILSpy/Options/DecompilerSettingsPanel.xaml | 125 ++++++------ ILSpy/Options/DisplaySettingsPanel.xaml | 215 +++++++++++---------- ILSpy/Search/SearchPane.xaml | 161 +++++++-------- ILSpy/Themes/generic.xaml | 63 +++--- SharpTreeView/ICSharpCode.TreeView.csproj | 1 + SharpTreeView/SharpTreeView.cs | 2 +- SharpTreeView/SharpTreeViewItem.cs | 2 +- SharpTreeView/Themes/Generic.xaml | 10 +- 12 files changed, 334 insertions(+), 301 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 324ee40f21..a8af6e158e 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -9,6 +9,7 @@ + diff --git a/ILSpy/App.xaml b/ILSpy/App.xaml index 151558268e..62f880e7b6 100644 --- a/ILSpy/App.xaml +++ b/ILSpy/App.xaml @@ -5,25 +5,43 @@ xmlns:toms="urn:TomsToolbox" xmlns:ilSpy="clr-namespace:ICSharpCode.ILSpy" xmlns:themes="clr-namespace:ICSharpCode.ILSpy.Themes" + xmlns:ws="https://schemas.elecho.dev/wpfsuite" StartupUri="MainWindow.xaml"> - - + + + + + + - + \ No newline at end of file diff --git a/ILSpy/Controls/ZoomScrollViewer.cs b/ILSpy/Controls/ZoomScrollViewer.cs index dff54789cf..1b1400b43d 100644 --- a/ILSpy/Controls/ZoomScrollViewer.cs +++ b/ILSpy/Controls/ZoomScrollViewer.cs @@ -30,7 +30,7 @@ namespace ICSharpCode.ILSpy.Controls { - public class ZoomScrollViewer : ScrollViewer + public class ZoomScrollViewer : EleCho.WpfSuite.ScrollViewer { static ZoomScrollViewer() { diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index 0ecb0caad8..c155a330fe 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -45,6 +45,7 @@ + diff --git a/ILSpy/Options/DecompilerSettingsPanel.xaml b/ILSpy/Options/DecompilerSettingsPanel.xaml index 9444a4cdc8..0f89785f0f 100644 --- a/ILSpy/Options/DecompilerSettingsPanel.xaml +++ b/ILSpy/Options/DecompilerSettingsPanel.xaml @@ -1,63 +1,68 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:properties="clr-namespace:ICSharpCode.ILSpy.Properties" + xmlns:options="clr-namespace:ICSharpCode.ILSpy.Options" + xmlns:ws="https://schemas.elecho.dev/wpfsuite"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ILSpy/Options/DisplaySettingsPanel.xaml b/ILSpy/Options/DisplaySettingsPanel.xaml index 52f5c3ab13..49395c3b23 100644 --- a/ILSpy/Options/DisplaySettingsPanel.xaml +++ b/ILSpy/Options/DisplaySettingsPanel.xaml @@ -1,109 +1,110 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 - 21 - 22 - 23 - 24 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:properties="clr-namespace:ICSharpCode.ILSpy.Properties" + xmlns:local="clr-namespace:ICSharpCode.ILSpy.Options" + xmlns:system="clr-namespace:System;assembly=mscorlib" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:themes="clr-namespace:ICSharpCode.ILSpy.Themes" + xmlns:ws="https://schemas.elecho.dev/wpfsuite" + d:DataContext="{d:DesignInstance local:DisplaySettingsViewModel}"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ILSpy/Search/SearchPane.xaml b/ILSpy/Search/SearchPane.xaml index a77da73341..25d21236d7 100644 --- a/ILSpy/Search/SearchPane.xaml +++ b/ILSpy/Search/SearchPane.xaml @@ -1,82 +1,83 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:controls="clr-namespace:ICSharpCode.ILSpy.Controls" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:properties="clr-namespace:ICSharpCode.ILSpy.Properties" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" x:Name="self" mc:Ignorable="d" + xmlns:ws="https://schemas.elecho.dev/wpfsuite" + d:DesignHeight="300" d:DesignWidth="300"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ILSpy/Themes/generic.xaml b/ILSpy/Themes/generic.xaml index de0378c657..4ffbf63741 100644 --- a/ILSpy/Themes/generic.xaml +++ b/ILSpy/Themes/generic.xaml @@ -1,34 +1,37 @@  - - - - - - - + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:controls="clr-namespace:ICSharpCode.ILSpy.Controls" + xmlns:themes="clr-namespace:ICSharpCode.ILSpy.Themes" + xmlns:ws="https://schemas.elecho.dev/wpfsuite"> - - - - - - - + + + + + + + + + + + + + + + + + GreenYellow + LightSeaGreen + Blue - GreenYellow - LightSeaGreen - Blue \ No newline at end of file diff --git a/SharpTreeView/ICSharpCode.TreeView.csproj b/SharpTreeView/ICSharpCode.TreeView.csproj index b59e5fde51..1998b5c391 100644 --- a/SharpTreeView/ICSharpCode.TreeView.csproj +++ b/SharpTreeView/ICSharpCode.TreeView.csproj @@ -22,6 +22,7 @@ + diff --git a/SharpTreeView/SharpTreeView.cs b/SharpTreeView/SharpTreeView.cs index d4de0673da..bf2268c128 100644 --- a/SharpTreeView/SharpTreeView.cs +++ b/SharpTreeView/SharpTreeView.cs @@ -30,7 +30,7 @@ namespace ICSharpCode.TreeView { - public class SharpTreeView : ListView + public class SharpTreeView : EleCho.WpfSuite.ListView { static SharpTreeView() { diff --git a/SharpTreeView/SharpTreeViewItem.cs b/SharpTreeView/SharpTreeViewItem.cs index 6785b1f852..21ac0c3e6e 100644 --- a/SharpTreeView/SharpTreeViewItem.cs +++ b/SharpTreeView/SharpTreeViewItem.cs @@ -24,7 +24,7 @@ namespace ICSharpCode.TreeView { - public class SharpTreeViewItem : ListViewItem + public class SharpTreeViewItem : EleCho.WpfSuite.ListViewItem { static SharpTreeViewItem() { diff --git a/SharpTreeView/Themes/Generic.xaml b/SharpTreeView/Themes/Generic.xaml index 5d3109b351..9bb6146f7f 100644 --- a/SharpTreeView/Themes/Generic.xaml +++ b/SharpTreeView/Themes/Generic.xaml @@ -1,7 +1,8 @@ + xmlns:styles="urn:TomsToolbox.Wpf.Styles" + xmlns:ws="https://schemas.elecho.dev/wpfsuite"> + + + \ No newline at end of file diff --git a/EleCho.WpfSuite/Controls/ListBoxResources.xaml b/EleCho.WpfSuite/Controls/ListBoxResources.xaml new file mode 100644 index 0000000000..89e21560f8 --- /dev/null +++ b/EleCho.WpfSuite/Controls/ListBoxResources.xaml @@ -0,0 +1,73 @@ + + + + + + + + \ No newline at end of file diff --git a/EleCho.WpfSuite/Controls/ListView.cs b/EleCho.WpfSuite/Controls/ListView.cs new file mode 100644 index 0000000000..fd9f8ea47f --- /dev/null +++ b/EleCho.WpfSuite/Controls/ListView.cs @@ -0,0 +1,75 @@ +using System.Windows; +using System.Windows.Media; + +namespace EleCho.WpfSuite +{ + /// + public class ListView : System.Windows.Controls.ListView + { + static ListView() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ListView), new FrameworkPropertyMetadata(typeof(ListView))); + } + + + /// + /// The CornerRadius property allows users to control the roundness of the corners independently by + /// setting a radius value for each corner. Radius values that are too large are scaled so that they + /// smoothly blend from corner to corner. + /// + public CornerRadius CornerRadius + { + get { return (CornerRadius)GetValue(CornerRadiusProperty); } + set { SetValue(CornerRadiusProperty, value); } + } + + /// + /// Background when disabled + /// + public Brush DisabledBackground + { + get { return (Brush)GetValue(DisabledBackgroundProperty); } + set { SetValue(DisabledBackgroundProperty, value); } + } + + /// + /// BorderBrush when pressed by mouse + /// + public Brush DisabledBorderBrush + { + get { return (Brush)GetValue(DisabledBorderBrushProperty); } + set { SetValue(DisabledBorderBrushProperty, value); } + } + + /// + protected override DependencyObject GetContainerForItemOverride() + { + return new ListViewItem(); + } + + /// + protected override bool IsItemItsOwnContainerOverride(object item) + { + return item is ListViewItem; + } + + + /// + /// DependencyProperty of property + /// + public static readonly DependencyProperty CornerRadiusProperty = + Border.CornerRadiusProperty.AddOwner(typeof(ListView)); + + /// + /// The DependencyProperty of property + /// + public static readonly DependencyProperty DisabledBackgroundProperty = + DependencyProperty.Register(nameof(DisabledBackground), typeof(Brush), typeof(ListView), new FrameworkPropertyMetadata(null)); + + /// + /// The DependencyProperty of property + /// + public static readonly DependencyProperty DisabledBorderBrushProperty = + DependencyProperty.Register(nameof(DisabledBorderBrush), typeof(Brush), typeof(ListView), new FrameworkPropertyMetadata(null)); + } +} diff --git a/EleCho.WpfSuite/Controls/ListViewItem.cs b/EleCho.WpfSuite/Controls/ListViewItem.cs new file mode 100644 index 0000000000..669eedd82b --- /dev/null +++ b/EleCho.WpfSuite/Controls/ListViewItem.cs @@ -0,0 +1,136 @@ +using System.Windows; +using System.Windows.Media; + +namespace EleCho.WpfSuite +{ + public class ListViewItem : System.Windows.Controls.ListViewItem + { + static ListViewItem() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ListViewItem), new FrameworkPropertyMetadata(typeof(ListViewItem))); + } + + /// + /// The CornerRadius property allows users to control the roundness of the corners independently by + /// setting a radius value for each corner. Radius values that are too large are scaled so that they + /// smoothly blend from corner to corner. + /// + public CornerRadius CornerRadius + { + get { return (CornerRadius)GetValue(CornerRadiusProperty); } + set { SetValue(CornerRadiusProperty, value); } + } + public Brush HoverForeground + { + get { return (Brush)GetValue(HoverForegroundProperty); } + set { SetValue(HoverForegroundProperty, value); } + } + + public Brush HoverBackground + { + get { return (Brush)GetValue(HoverBackgroundProperty); } + set { SetValue(HoverBackgroundProperty, value); } + } + + public Brush HoverBorderBrush + { + get { return (Brush)GetValue(HoverBorderBrushProperty); } + set { SetValue(HoverBorderBrushProperty, value); } + } + + public Brush SelectedForeground + { + get { return (Brush)GetValue(SelectedForegroundProperty); } + set { SetValue(SelectedForegroundProperty, value); } + } + + public Brush SelectedBackground + { + get { return (Brush)GetValue(SelectedBackgroundProperty); } + set { SetValue(SelectedBackgroundProperty, value); } + } + + public Brush SelectedBorderBrush + { + get { return (Brush)GetValue(SelectedBorderBrushProperty); } + set { SetValue(SelectedBorderBrushProperty, value); } + } + + public Brush SelectedActiveForeground + { + get { return (Brush)GetValue(SelectedActiveForegroundProperty); } + set { SetValue(SelectedActiveForegroundProperty, value); } + } + + public Brush SelectedActiveBackground + { + get { return (Brush)GetValue(SelectedActiveBackgroundProperty); } + set { SetValue(SelectedActiveBackgroundProperty, value); } + } + + public Brush SelectedActiveBorderBrush + { + get { return (Brush)GetValue(SelectedActiveBorderBrushProperty); } + set { SetValue(SelectedActiveBorderBrushProperty, value); } + } + + public Brush DisabledForeground + { + get { return (Brush)GetValue(DisabledForegroundProperty); } + set { SetValue(DisabledForegroundProperty, value); } + } + + public Brush DisabledBackground + { + get { return (Brush)GetValue(DisabledBackgroundProperty); } + set { SetValue(DisabledBackgroundProperty, value); } + } + + public Brush DisabledBorderBrush + { + get { return (Brush)GetValue(DisabledBorderBrushProperty); } + set { SetValue(DisabledBorderBrushProperty, value); } + } + + + public static readonly DependencyProperty CornerRadiusProperty = + Border.CornerRadiusProperty.AddOwner(typeof(ListViewItem)); + + + public static readonly DependencyProperty HoverForegroundProperty = + DependencyProperty.Register(nameof(HoverForeground), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty HoverBackgroundProperty = + DependencyProperty.Register(nameof(HoverBackground), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty HoverBorderBrushProperty = + DependencyProperty.Register(nameof(HoverBorderBrush), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty SelectedForegroundProperty = + DependencyProperty.Register(nameof(SelectedForeground), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty SelectedBackgroundProperty = + DependencyProperty.Register(nameof(SelectedBackground), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty SelectedBorderBrushProperty = + DependencyProperty.Register(nameof(SelectedBorderBrush), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty SelectedActiveForegroundProperty = + DependencyProperty.Register(nameof(SelectedActiveForeground), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty SelectedActiveBackgroundProperty = + DependencyProperty.Register(nameof(SelectedActiveBackground), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty SelectedActiveBorderBrushProperty = + DependencyProperty.Register(nameof(SelectedActiveBorderBrush), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty DisabledForegroundProperty = + DependencyProperty.Register(nameof(DisabledForeground), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty DisabledBackgroundProperty = + DependencyProperty.Register(nameof(DisabledBackground), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty DisabledBorderBrushProperty = + DependencyProperty.Register(nameof(DisabledBorderBrush), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); + } +} diff --git a/EleCho.WpfSuite/Controls/ListViewItemResources.xaml b/EleCho.WpfSuite/Controls/ListViewItemResources.xaml new file mode 100644 index 0000000000..517ad8a834 --- /dev/null +++ b/EleCho.WpfSuite/Controls/ListViewItemResources.xaml @@ -0,0 +1,174 @@ + + + + + + \ No newline at end of file diff --git a/EleCho.WpfSuite/Controls/ListViewResources.xaml b/EleCho.WpfSuite/Controls/ListViewResources.xaml new file mode 100644 index 0000000000..9dcc36b27a --- /dev/null +++ b/EleCho.WpfSuite/Controls/ListViewResources.xaml @@ -0,0 +1,73 @@ + + + + + + + + \ No newline at end of file diff --git a/EleCho.WpfSuite/Controls/RepeatButton.cs b/EleCho.WpfSuite/Controls/RepeatButton.cs new file mode 100644 index 0000000000..cbae4199dc --- /dev/null +++ b/EleCho.WpfSuite/Controls/RepeatButton.cs @@ -0,0 +1,113 @@ +using System.Windows; +using System.Windows.Media; + +namespace EleCho.WpfSuite +{ + public class RepeatButton : System.Windows.Controls.Primitives.RepeatButton + { + static RepeatButton() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(RepeatButton), new FrameworkPropertyMetadata(typeof(RepeatButton))); + } + + public CornerRadius CornerRadius + { + get { return (CornerRadius)GetValue(CornerRadiusProperty); } + set { SetValue(CornerRadiusProperty, value); } + } + + public Brush HoverForeground + { + get { return (Brush)GetValue(HoverForegroundProperty); } + set { SetValue(HoverForegroundProperty, value); } + } + + public Brush HoverBackground + { + get { return (Brush)GetValue(HoverBackgroundProperty); } + set { SetValue(HoverBackgroundProperty, value); } + } + + public Brush HoverBorderBrush + { + get { return (Brush)GetValue(HoverBorderBrushProperty); } + set { SetValue(HoverBorderBrushProperty, value); } + } + + public Brush PressedForeground + { + get { return (Brush)GetValue(PressedForegroundProperty); } + set { SetValue(PressedForegroundProperty, value); } + } + + public Brush PressedBackground + { + get { return (Brush)GetValue(PressedBackgroundProperty); } + set { SetValue(PressedBackgroundProperty, value); } + } + + public Brush PressedBorderBrush + { + get { return (Brush)GetValue(PressedBorderBrushProperty); } + set { SetValue(PressedBorderBrushProperty, value); } + } + + public Brush DisabledForeground + { + get { return (Brush)GetValue(DisabledForegroundProperty); } + set { SetValue(DisabledForegroundProperty, value); } + } + + public Brush DisabledBackground + { + get { return (Brush)GetValue(DisabledBackgroundProperty); } + set { SetValue(DisabledBackgroundProperty, value); } + } + + public Brush DisabledBorderBrush + { + get { return (Brush)GetValue(DisabledBorderBrushProperty); } + set { SetValue(DisabledBorderBrushProperty, value); } + } + + public Brush HighlightBrush + { + get { return (Brush)GetValue(HighlightBrushProperty); } + set { SetValue(HighlightBrushProperty, value); } + } + + + public static readonly DependencyProperty CornerRadiusProperty = + Border.CornerRadiusProperty.AddOwner(typeof(RepeatButton)); + + public static readonly DependencyProperty HoverForegroundProperty = + DependencyProperty.Register(nameof(HoverForeground), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty HoverBackgroundProperty = + DependencyProperty.Register(nameof(HoverBackground), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty HoverBorderBrushProperty = + DependencyProperty.Register(nameof(HoverBorderBrush), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty PressedForegroundProperty = + DependencyProperty.Register(nameof(PressedForeground), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty PressedBackgroundProperty = + DependencyProperty.Register(nameof(PressedBackground), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty PressedBorderBrushProperty = + DependencyProperty.Register(nameof(PressedBorderBrush), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty DisabledForegroundProperty = + DependencyProperty.Register(nameof(DisabledForeground), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty DisabledBackgroundProperty = + DependencyProperty.Register(nameof(DisabledBackground), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty DisabledBorderBrushProperty = + DependencyProperty.Register(nameof(DisabledBorderBrush), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty HighlightBrushProperty = + DependencyProperty.Register(nameof(HighlightBrush), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(SystemColors.HighlightBrush)); + } +} diff --git a/EleCho.WpfSuite/Controls/RepeatButtonResources.xaml b/EleCho.WpfSuite/Controls/RepeatButtonResources.xaml new file mode 100644 index 0000000000..97495d7179 --- /dev/null +++ b/EleCho.WpfSuite/Controls/RepeatButtonResources.xaml @@ -0,0 +1,150 @@ + + + + + \ No newline at end of file diff --git a/EleCho.WpfSuite/Controls/ScrollBar.cs b/EleCho.WpfSuite/Controls/ScrollBar.cs new file mode 100644 index 0000000000..e4d420cca5 --- /dev/null +++ b/EleCho.WpfSuite/Controls/ScrollBar.cs @@ -0,0 +1,234 @@ +using System.Windows; +using System.Windows.Media; + +namespace EleCho.WpfSuite +{ + public class ScrollBar : System.Windows.Controls.Primitives.ScrollBar + { + private static readonly Brush s_thumbBrush =new SolidColorBrush(Color.FromRgb(205, 205, 205)); + private static readonly Brush s_glyphBrush= new SolidColorBrush(Color.FromRgb(96, 96, 96)); + private static readonly Brush s_disabledGlyphBrush =new SolidColorBrush(Color.FromRgb(112, 112, 112)); + private static readonly Geometry s_glyphLeft = Geometry.Parse("M 3.18,7 C3.18,7 5,7 5,7 5,7 1.81,3.5 1.81,3.5 1.81,3.5 5,0 5,0 5,0 3.18,0 3.18,0 3.18,0 0,3.5 0,3.5 0,3.5 3.18,7 3.18,7 z"); + private static readonly Geometry s_glyphRight = Geometry.Parse("M 1.81,7 C1.81,7 0,7 0,7 0,7 3.18,3.5 3.18,3.5 3.18,3.5 0,0 0,0 0,0 1.81,0 1.81,0 1.81,0 5,3.5 5,3.5 5,3.5 1.81,7 1.81,7 z"); + private static readonly Geometry s_glyphUp = Geometry.Parse("M 0,4 C0,4 0,6 0,6 0,6 3.5,2.5 3.5,2.5 3.5,2.5 7,6 7,6 7,6 7,4 7,4 7,4 3.5,0.5 3.5,0.5 3.5,0.5 0,4 0,4 z"); + private static readonly Geometry s_glyphDown = Geometry.Parse("M 0,2.5 C0,2.5 0,0.5 0,0.5 0,0.5 3.5,4 3.5,4 3.5,4 7,0.5 7,0.5 7,0.5 7,2.5 7,2.5 7,2.5 3.5,6 3.5,6 3.5,6 0,2.5 0,2.5 z"); + + static ScrollBar() + { + s_thumbBrush.Freeze(); + s_glyphBrush.Freeze(); + s_disabledGlyphBrush.Freeze(); + + s_glyphLeft.Freeze(); + s_glyphRight.Freeze(); + s_glyphUp.Freeze(); + s_glyphDown.Freeze(); + + DefaultStyleKeyProperty.OverrideMetadata(typeof(ScrollBar), new FrameworkPropertyMetadata(typeof(ScrollBar))); + } + + + public CornerRadius CornerRadius + { + get { return (CornerRadius)GetValue(CornerRadiusProperty); } + set { SetValue(CornerRadiusProperty, value); } + } + + public CornerRadius ThumbCornerRadius + { + get { return (CornerRadius)GetValue(ThumbCornerRadiusProperty); } + set { SetValue(ThumbCornerRadiusProperty, value); } + } + + public CornerRadius ButtonCornerRadius + { + get { return (CornerRadius)GetValue(ButtonCornerRadiusProperty); } + set { SetValue(ButtonCornerRadiusProperty, value); } + } + + public Thickness GlyphMargin + { + get { return (Thickness)GetValue(GlyphMarginProperty); } + set { SetValue(GlyphMarginProperty, value); } + } + + + + public Geometry? ArrowLeftGlyph + { + get { return (Geometry?)GetValue(ArrowLeftGlyphProperty); } + set { SetValue(ArrowLeftGlyphProperty, value); } + } + + public Geometry? ArrowRightGlyph + { + get { return (Geometry?)GetValue(ArrowRightGlyphProperty); } + set { SetValue(ArrowRightGlyphProperty, value); } + } + + public Geometry? ArrowUpGlyph + { + get { return (Geometry?)GetValue(ArrowUpGlyphProperty); } + set { SetValue(ArrowUpGlyphProperty, value); } + } + + public Geometry? ArrowDownGlyph + { + get { return (Geometry?)GetValue(ArrowDownGlyphProperty); } + set { SetValue(ArrowDownGlyphProperty, value); } + } + + public Brush ThumbBrush + { + get { return (Brush)GetValue(ThumbBrushProperty); } + set { SetValue(ThumbBrushProperty, value); } + } + + public Brush GlyphBrush + { + get { return (Brush)GetValue(GlyphBrushProperty); } + set { SetValue(GlyphBrushProperty, value); } + } + + public Brush HoverBackground + { + get { return (Brush)GetValue(HoverBackgroundProperty); } + set { SetValue(HoverBackgroundProperty, value); } + } + + public Brush HoverBorderBrush + { + get { return (Brush)GetValue(HoverBorderBrushProperty); } + set { SetValue(HoverBorderBrushProperty, value); } + } + + public Brush HoverThumbBrush + { + get { return (Brush)GetValue(HoverThumbBrushProperty); } + set { SetValue(HoverThumbBrushProperty, value); } + } + + public Brush HoverGlyphBrush + { + get { return (Brush)GetValue(HoverGlyphBrushProperty); } + set { SetValue(HoverGlyphBrushProperty, value); } + } + + public Brush PressedBackground + { + get { return (Brush)GetValue(PressedBackgroundProperty); } + set { SetValue(PressedBackgroundProperty, value); } + } + + public Brush PressedBorderBrush + { + get { return (Brush)GetValue(PressedBorderBrushProperty); } + set { SetValue(PressedBorderBrushProperty, value); } + } + + public Brush PressedThumbBrush + { + get { return (Brush)GetValue(PressedThumbBrushProperty); } + set { SetValue(PressedThumbBrushProperty, value); } + } + + public Brush PressedGlyphBrush + { + get { return (Brush)GetValue(PressedGlyphBrushProperty); } + set { SetValue(PressedGlyphBrushProperty, value); } + } + + public Brush DisabledBackground + { + get { return (Brush)GetValue(DisabledBackgroundProperty); } + set { SetValue(DisabledBackgroundProperty, value); } + } + + public Brush DisabledBorderBrush + { + get { return (Brush)GetValue(DisabledBorderBrushProperty); } + set { SetValue(DisabledBorderBrushProperty, value); } + } + + public Brush DisabledThumbBrush + { + get { return (Brush)GetValue(DisabledThumbBrushProperty); } + set { SetValue(DisabledThumbBrushProperty, value); } + } + + public Brush DisabledGlyphBrush + { + get { return (Brush)GetValue(DisabledGlyphBrushProperty); } + set { SetValue(DisabledGlyphBrushProperty, value); } + } + + + + + public static readonly DependencyProperty CornerRadiusProperty = + Border.CornerRadiusProperty.AddOwner(typeof(ScrollBar)); + + public static readonly DependencyProperty ThumbCornerRadiusProperty = + DependencyProperty.Register(nameof(ThumbCornerRadius), typeof(CornerRadius), typeof(ScrollBar), new FrameworkPropertyMetadata(new CornerRadius(0))); + + public static readonly DependencyProperty ButtonCornerRadiusProperty = + DependencyProperty.Register(nameof(ButtonCornerRadius), typeof(CornerRadius), typeof(ScrollBar), new FrameworkPropertyMetadata(new CornerRadius(0))); + + public static readonly DependencyProperty GlyphMarginProperty = + DependencyProperty.Register(nameof(GlyphMargin), typeof(Thickness), typeof(ScrollBar), new FrameworkPropertyMetadata(new Thickness(3))); + + public static readonly DependencyProperty ArrowLeftGlyphProperty = + DependencyProperty.Register(nameof(ArrowLeftGlyph), typeof(Geometry), typeof(ScrollBar), new FrameworkPropertyMetadata(s_glyphLeft)); + + public static readonly DependencyProperty ArrowRightGlyphProperty = + DependencyProperty.Register(nameof(ArrowRightGlyph), typeof(Geometry), typeof(ScrollBar), new FrameworkPropertyMetadata(s_glyphRight)); + + public static readonly DependencyProperty ArrowUpGlyphProperty = + DependencyProperty.Register(nameof(ArrowUpGlyph), typeof(Geometry), typeof(ScrollBar), new FrameworkPropertyMetadata(s_glyphUp)); + + public static readonly DependencyProperty ArrowDownGlyphProperty = + DependencyProperty.Register(nameof(ArrowDownGlyph), typeof(Geometry), typeof(ScrollBar), new FrameworkPropertyMetadata(s_glyphDown)); + + public static readonly DependencyProperty ThumbBrushProperty = + DependencyProperty.Register(nameof(ThumbBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(s_thumbBrush)); + + public static readonly DependencyProperty GlyphBrushProperty = + DependencyProperty.Register(nameof(GlyphBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(s_glyphBrush)); + + public static readonly DependencyProperty HoverBackgroundProperty = + DependencyProperty.Register(nameof(HoverBackground), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty HoverBorderBrushProperty = + DependencyProperty.Register(nameof(HoverBorderBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty HoverThumbBrushProperty = + DependencyProperty.Register(nameof(HoverThumbBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty HoverGlyphBrushProperty = + DependencyProperty.Register(nameof(HoverGlyphBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty PressedBackgroundProperty = + DependencyProperty.Register(nameof(PressedBackground), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty PressedBorderBrushProperty = + DependencyProperty.Register(nameof(PressedBorderBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty PressedThumbBrushProperty = + DependencyProperty.Register(nameof(PressedThumbBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty PressedGlyphBrushProperty = + DependencyProperty.Register(nameof(PressedGlyphBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty DisabledBackgroundProperty = + DependencyProperty.Register(nameof(DisabledBackground), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty DisabledBorderBrushProperty = + DependencyProperty.Register(nameof(DisabledBorderBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty DisabledThumbBrushProperty = + DependencyProperty.Register(nameof(DisabledThumbBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty DisabledGlyphBrushProperty = + DependencyProperty.Register(nameof(DisabledGlyphBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(s_disabledGlyphBrush)); + } +} diff --git a/EleCho.WpfSuite/Controls/ScrollBarResources.xaml b/EleCho.WpfSuite/Controls/ScrollBarResources.xaml new file mode 100644 index 0000000000..c4dab43ba1 --- /dev/null +++ b/EleCho.WpfSuite/Controls/ScrollBarResources.xaml @@ -0,0 +1,514 @@ + + + + + + + + \ No newline at end of file diff --git a/EleCho.WpfSuite/Controls/ScrollViewer.cs b/EleCho.WpfSuite/Controls/ScrollViewer.cs new file mode 100644 index 0000000000..82b9d7b1af --- /dev/null +++ b/EleCho.WpfSuite/Controls/ScrollViewer.cs @@ -0,0 +1,456 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Interop; +using System.Windows.Media; +using System.Windows.Media.Animation; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace EleCho.WpfSuite +{ + /// + public class ScrollViewer : System.Windows.Controls.ScrollViewer + { + static ScrollViewer() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ScrollViewer), new FrameworkPropertyMetadata(typeof(ScrollViewer))); + +#if NETCOREAPP + _propertyHandlesMouseWheelScrollingGetter = typeof(ScrollViewer) + .GetProperty("HandlesMouseWheelScrolling", BindingFlags.Instance | BindingFlags.NonPublic)! + .GetGetMethod(true)! + .CreateDelegate(); +#else + _propertyHandlesMouseWheelScrollingGetter = (GetBool)typeof(ScrollViewer) + .GetProperty("HandlesMouseWheelScrolling", BindingFlags.Instance | BindingFlags.NonPublic)! + .GetGetMethod(true)! + .CreateDelegate(typeof(GetBool)); +#endif + } + + private delegate bool GetBool(ScrollViewer scrollViewer); + private static readonly GetBool _propertyHandlesMouseWheelScrollingGetter; + private static readonly IEasingFunction _scrollingAnimationEase = new CubicEase(){ EasingMode = EasingMode.EaseOut }; + private const long _millisecondsBetweenTouchpadScrolling = 100; + + private bool _animationRunning = false; + private int _lastScrollDelta = 0; + private int _lastVerticalScrollingDelta = 0; + private int _lastHorizontalScrollingDelta = 0; + private long _lastScrollingTick; + + private FrameworkElement? _scrollContentPresenter; + + /// + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + _scrollContentPresenter = GetTemplateChild("PART_ScrollContentPresenter") as FrameworkElement; + } + + private void CoreScrollWithWheelDelta(MouseWheelEventArgs e) + { + if (e.Handled) + { + return; + } + + if (!AlwaysHandleMouseWheelScrolling && + !_propertyHandlesMouseWheelScrollingGetter.Invoke(this)) + { + return; + } + + bool vertical = ExtentHeight > 0; + bool horizontal = ExtentWidth > 0; + + var tickCount = Environment.TickCount; + var isTouchpadScrolling = + e.Delta % Mouse.MouseWheelDeltaForOneLine != 0 || + (tickCount - _lastScrollingTick < _millisecondsBetweenTouchpadScrolling && _lastScrollDelta % Mouse.MouseWheelDeltaForOneLine != 0); + + double scrollDelta = e.Delta; + + if (isTouchpadScrolling) + { + // touchpad 应该滚动更慢一些, 所以这里预先除以一个合适的值 + scrollDelta /= 2; + + // + scrollDelta *= TouchpadScrollDeltaFactor; + } + else + { + scrollDelta *= MouseScrollDeltaFactor; + } + + if (vertical) + { + if (ScrollInfo is IScrollInfo scrollInfo) + { + // 考虑到 VirtualizingPanel 可能是虚拟的大小, 所以这里需要校正 Delta + scrollDelta *= scrollInfo.ViewportHeight / (_scrollContentPresenter?.ActualHeight ?? ActualHeight); + } + + var sameDirectionAsLast = Math.Sign(e.Delta) == Math.Sign(_lastVerticalScrollingDelta); + var nowOffset = sameDirectionAsLast && _animationRunning ? VerticalOffsetTarget : VerticalOffset; + var newOffset = nowOffset - scrollDelta; + + if (newOffset < 0) + newOffset = 0; + if (newOffset > ScrollableHeight) + newOffset = ScrollableHeight; + + SetValue(VerticalOffsetTargetPropertyKey, newOffset); + BeginAnimation(ScrollViewerUtils.VerticalOffsetProperty, null); + + if (!EnableScrollingAnimation || isTouchpadScrolling) + { + ScrollToVerticalOffset(newOffset); + } + else + { + var diff = newOffset - VerticalOffset; + var absDiff = Math.Abs(diff); + var duration = ScrollingAnimationDuration; + if (absDiff < Mouse.MouseWheelDeltaForOneLine) + { + duration = new Duration(TimeSpan.FromTicks((long)(duration.TimeSpan.Ticks * absDiff / Mouse.MouseWheelDeltaForOneLine))); + } + + DoubleAnimation doubleAnimation = new DoubleAnimation() + { + EasingFunction = _scrollingAnimationEase, + Duration = duration, + From = VerticalOffset, + To = newOffset, + }; + + doubleAnimation.Completed += DoubleAnimation_Completed; + + _animationRunning = true; + BeginAnimation(ScrollViewerUtils.VerticalOffsetProperty, doubleAnimation, HandoffBehavior.SnapshotAndReplace); + } + + _lastVerticalScrollingDelta = e.Delta; + } + else if (horizontal) + { + if (ScrollInfo is IScrollInfo scrollInfo) + { + // 考虑到 VirtualizingPanel 可能是虚拟的大小, 所以这里需要校正 Delta + scrollDelta *= scrollInfo.ViewportWidth / (_scrollContentPresenter?.ActualWidth ?? ActualWidth); + } + + var sameDirectionAsLast = Math.Sign(e.Delta) == Math.Sign(_lastHorizontalScrollingDelta); + var nowOffset = sameDirectionAsLast && _animationRunning ? HorizontalOffsetTarget : HorizontalOffset; + var newOffset = nowOffset - scrollDelta; + + if (newOffset < 0) + newOffset = 0; + if (newOffset > ScrollableWidth) + newOffset = ScrollableWidth; + + SetValue(HorizontalOffsetTargetPropertyKey, newOffset); + BeginAnimation(ScrollViewerUtils.HorizontalOffsetProperty, null); + + if (!EnableScrollingAnimation || isTouchpadScrolling) + { + ScrollToHorizontalOffset(newOffset); + } + else + { + var diff = newOffset - HorizontalOffset; + var absDiff = Math.Abs(diff); + var duration = ScrollingAnimationDuration; + if (absDiff < Mouse.MouseWheelDeltaForOneLine) + { + duration = new Duration(TimeSpan.FromTicks((long)(duration.TimeSpan.Ticks * absDiff / Mouse.MouseWheelDeltaForOneLine))); + } + + DoubleAnimation doubleAnimation = new DoubleAnimation() + { + EasingFunction = _scrollingAnimationEase, + Duration = duration, + From = HorizontalOffset, + To = newOffset, + }; + + doubleAnimation.Completed += DoubleAnimation_Completed; + + _animationRunning = true; + BeginAnimation(ScrollViewerUtils.HorizontalOffsetProperty, doubleAnimation, HandoffBehavior.SnapshotAndReplace); + } + + _lastHorizontalScrollingDelta = e.Delta; + } + + _lastScrollingTick = tickCount; + _lastScrollDelta = e.Delta; + + e.Handled = true; + } + + private void DoubleAnimation_Completed(object? sender, EventArgs e) + { + _animationRunning = false; + } + + /// + protected override void OnMouseWheel(MouseWheelEventArgs e) + { + if (!ScrollWithWheelDelta) + { + base.OnMouseWheel(e); + } + else + { + Debug.WriteLine(e.Delta); + + CoreScrollWithWheelDelta(e); + } + } + + /// + /// The horizontal offset of scrolling target + /// + public double HorizontalOffsetTarget + { + get { return (double)GetValue(HorizontalOffsetTargetProperty); } + } + + /// + /// The vertical offset of scrolling target + /// + public double VerticalOffsetTarget + { + get { return (double)GetValue(VerticalOffsetTargetProperty); } + } + + /// + /// Scroll with wheel delta instead of scrolling fixed number of lines + /// + public bool ScrollWithWheelDelta + { + get { return (bool)GetValue(ScrollWithWheelDeltaProperty); } + set { SetValue(ScrollWithWheelDeltaProperty, value); } + } + + /// + /// Enable scrolling animation while using mouse
+ /// You need to set ScrollWithWheelDelta to true to use this + ///
+ public bool EnableScrollingAnimation + { + get { return (bool)GetValue(EnableScrollingAnimationProperty); } + set { SetValue(EnableScrollingAnimationProperty, value); } + } + + /// + /// Scrolling animation duration + /// + public Duration ScrollingAnimationDuration + { + get { return (Duration)GetValue(ScrollingAnimationDurationProperty); } + set { SetValue(ScrollingAnimationDurationProperty, value); } + } + + /// + /// Delta value factor while mouse scrolling + /// + public double MouseScrollDeltaFactor + { + get { return (double)GetValue(MouseScrollDeltaFactorProperty); } + set { SetValue(MouseScrollDeltaFactorProperty, value); } + } + + /// + /// Delta value factor while touchpad scrolling + /// + public double TouchpadScrollDeltaFactor + { + get { return (double)GetValue(TouchpadScrollDeltaFactorProperty); } + set { SetValue(TouchpadScrollDeltaFactorProperty, value); } + } + + /// + /// Always handle mouse wheel scrolling.
+ /// (Especially in "TextBox") + ///
+ public bool AlwaysHandleMouseWheelScrolling + { + get { return (bool)GetValue(AlwaysHandleMouseWheelScrollingProperty); } + set { SetValue(AlwaysHandleMouseWheelScrollingProperty, value); } + } + + + + + + + + + /// + /// The key needed set a read-only property + /// + public static readonly DependencyPropertyKey HorizontalOffsetTargetPropertyKey = + DependencyProperty.RegisterReadOnly(nameof(HorizontalOffsetTarget), typeof(double), typeof(ScrollViewer), new PropertyMetadata(0.0)); + + /// + /// The key needed set a read-only property + /// + public static readonly DependencyPropertyKey VerticalOffsetTargetPropertyKey = + DependencyProperty.RegisterReadOnly(nameof(VerticalOffsetTarget), typeof(double), typeof(ScrollViewer), new PropertyMetadata(0.0)); + + /// + /// The key needed set a read-only property + /// + public static readonly DependencyProperty HorizontalOffsetTargetProperty = + HorizontalOffsetTargetPropertyKey.DependencyProperty; + + /// + /// The key needed set a read-only property + /// + public static readonly DependencyProperty VerticalOffsetTargetProperty = + VerticalOffsetTargetPropertyKey.DependencyProperty; + + + + /// + /// Get value of ScrollWithWheelDelta property + /// + /// + /// + public static bool GetScrollWithWheelDelta(DependencyObject obj) + { + return (bool)obj.GetValue(ScrollWithWheelDeltaProperty); + } + + /// + /// Set value of ScrollWithWheelDelta property + /// + /// + /// + public static void SetScrollWithWheelDelta(DependencyObject obj, bool value) + { + obj.SetValue(ScrollWithWheelDeltaProperty, value); + } + + /// + /// Get value of EnableScrollingAnimation property + /// + /// + /// + public static bool GetEnableScrollingAnimation(DependencyObject obj) + { + return (bool)obj.GetValue(EnableScrollingAnimationProperty); + } + + /// + /// Set value of EnableScrollingAnimation property + /// + /// + /// + public static void SetEnableScrollingAnimation(DependencyObject obj, bool value) + { + obj.SetValue(EnableScrollingAnimationProperty, value); + } + + /// + /// Get value of ScrollingAnimationDuration property + /// + /// + /// + public static Duration GetScrollingAnimationDuration(DependencyObject obj) + { + return (Duration)obj.GetValue(ScrollingAnimationDurationProperty); + } + + /// + /// Set value of ScrollingAnimationDuration property + /// + /// + /// + public static void SetScrollingAnimationDuration(DependencyObject obj, Duration value) + { + obj.SetValue(ScrollingAnimationDurationProperty, value); + } + + + /// + /// Set value of AlwaysHandleMouseWheelScrolling property + /// + /// + /// + public static bool GetAlwaysHandleMouseWheelScrolling(DependencyObject obj) + { + return (bool)obj.GetValue(AlwaysHandleMouseWheelScrollingProperty); + } + + /// + /// Get value of AlwaysHandleMouseWheelScrolling property + /// + /// + /// + public static void SetAlwaysHandleMouseWheelScrolling(DependencyObject obj, bool value) + { + obj.SetValue(AlwaysHandleMouseWheelScrollingProperty, value); + } + + + /// + /// The DependencyProperty of property. + /// + public static readonly DependencyProperty ScrollWithWheelDeltaProperty = + DependencyProperty.RegisterAttached(nameof(ScrollWithWheelDelta), typeof(bool), typeof(ScrollViewer), + new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits)); + + /// + /// The DependencyProperty of property. + /// + public static readonly DependencyProperty EnableScrollingAnimationProperty = + DependencyProperty.RegisterAttached(nameof(EnableScrollingAnimation), typeof(bool), typeof(ScrollViewer), + new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits)); + + /// + /// The DependencyProperty of property. + /// + public static readonly DependencyProperty ScrollingAnimationDurationProperty = + DependencyProperty.RegisterAttached(nameof(ScrollingAnimationDuration), typeof(Duration), typeof(ScrollViewer), + new FrameworkPropertyMetadata(new Duration(TimeSpan.FromMilliseconds(250)), FrameworkPropertyMetadataOptions.Inherits), ValidateScrollingAnimationDuration); + + /// + /// The DependencyProperty of property + /// + public static readonly DependencyProperty AlwaysHandleMouseWheelScrollingProperty = + DependencyProperty.RegisterAttached(nameof(AlwaysHandleMouseWheelScrolling), typeof(bool), typeof(ScrollViewer), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits)); + + /// + /// The DependencyProperty of property + /// + public static readonly DependencyProperty MouseScrollDeltaFactorProperty = + DependencyProperty.Register(nameof(MouseScrollDeltaFactor), typeof(double), typeof(ScrollViewer), new PropertyMetadata(1.0)); + + /// + /// The DependencyProperty of property + /// + public static readonly DependencyProperty TouchpadScrollDeltaFactorProperty = + DependencyProperty.Register(nameof(TouchpadScrollDeltaFactor), typeof(double), typeof(ScrollViewer), new PropertyMetadata(1.0)); + + private static bool ValidateScrollingAnimationDuration(object value) + => value is Duration duration && duration.HasTimeSpan; + } +} diff --git a/EleCho.WpfSuite/Controls/ScrollViewerResources.xaml b/EleCho.WpfSuite/Controls/ScrollViewerResources.xaml new file mode 100644 index 0000000000..68eef04cd0 --- /dev/null +++ b/EleCho.WpfSuite/Controls/ScrollViewerResources.xaml @@ -0,0 +1,34 @@ + + + + \ No newline at end of file diff --git a/EleCho.WpfSuite/Controls/Thumb.cs b/EleCho.WpfSuite/Controls/Thumb.cs new file mode 100644 index 0000000000..9580b3ce22 --- /dev/null +++ b/EleCho.WpfSuite/Controls/Thumb.cs @@ -0,0 +1,55 @@ +using System.Windows; +using System.Windows.Media; + +namespace EleCho.WpfSuite +{ + public class Thumb : System.Windows.Controls.Primitives.Thumb + { + static Thumb() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(Thumb), new FrameworkPropertyMetadata(typeof(Thumb))); + } + + /// + /// The CornerRadius property allows users to control the roundness of the corners independently by + /// setting a radius value for each corner. Radius values that are too large are scaled so that they + /// smoothly blend from corner to corner. + /// + public CornerRadius CornerRadius + { + get { return (CornerRadius)GetValue(CornerRadiusProperty); } + set { SetValue(CornerRadiusProperty, value); } + } + + public Brush HoverBackground + { + get { return (Brush)GetValue(HoverBackgroundProperty); } + set { SetValue(HoverBackgroundProperty, value); } + } + + public Brush PressedBackground + { + get { return (Brush)GetValue(PressedBackgroundProperty); } + set { SetValue(PressedBackgroundProperty, value); } + } + + public Brush DisabledBackground + { + get { return (Brush)GetValue(DisabledBackgroundProperty); } + set { SetValue(DisabledBackgroundProperty, value); } + } + + + public static readonly DependencyProperty CornerRadiusProperty = + Border.CornerRadiusProperty.AddOwner(typeof(Thumb)); + + public static readonly DependencyProperty HoverBackgroundProperty = + DependencyProperty.Register(nameof(HoverBackground), typeof(Brush), typeof(Thumb), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty PressedBackgroundProperty = + DependencyProperty.Register(nameof(PressedBackground), typeof(Brush), typeof(Thumb), new FrameworkPropertyMetadata(null)); + + public static readonly DependencyProperty DisabledBackgroundProperty = + DependencyProperty.Register(nameof(DisabledBackground), typeof(Brush), typeof(Thumb), new FrameworkPropertyMetadata(null)); + } +} diff --git a/EleCho.WpfSuite/Controls/ThumbResources.xaml b/EleCho.WpfSuite/Controls/ThumbResources.xaml new file mode 100644 index 0000000000..564d5ba5cc --- /dev/null +++ b/EleCho.WpfSuite/Controls/ThumbResources.xaml @@ -0,0 +1,34 @@ + + + + \ No newline at end of file diff --git a/EleCho.WpfSuite/EleCho.WpfSuite.csproj b/EleCho.WpfSuite/EleCho.WpfSuite.csproj new file mode 100644 index 0000000000..920f6a9b19 --- /dev/null +++ b/EleCho.WpfSuite/EleCho.WpfSuite.csproj @@ -0,0 +1,87 @@ + + + + net8.0-windows;net6.0-windows;net48;net47;net46;net45 + enable + latest + true + true + EleCho.WpfSuite + true + true + + 0.6.0 + + EleCho + Copyright © 2024 EleCho + https://wpfsuite.elecho.dev + logo.png + WPF;MVVM;XAML;Toolkit;Control;Layout;Transition;Converter;Animation;MarkupExtension;BindingProxy + WPF layout panels, controls, value converters, markup extensions, transitions and utilities + MIT + README.md + https://github.com/OrgEleCho/EleCho.WpfSuite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MSBuild:Compile + + + MSBuild:Compile + + + + + + + MSBuild:Compile + + + + + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + + diff --git a/EleCho.WpfSuite/MathHelper.cs b/EleCho.WpfSuite/MathHelper.cs new file mode 100644 index 0000000000..e82b1f018b --- /dev/null +++ b/EleCho.WpfSuite/MathHelper.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; +using System.Windows; + +namespace EleCho.WpfSuite +{ + internal static class MathHelper + { + internal const double DBL_EPSILON = 2.2204460492503131e-016; + + public static bool AreClose(double value1, double value2) => + // ReSharper disable once CompareOfFloatsByEqualityOperator + value1 == value2 || IsVerySmall(value1 - value2); + + public static double Lerp(double x, double y, double alpha) => x * (1.0 - alpha) + y * alpha; + + public static bool IsVerySmall(double value) => Math.Abs(value) < 1E-06; + + public static bool IsZero(double value) => Math.Abs(value) < 10.0 * DBL_EPSILON; + + public static bool IsFiniteDouble(double x) => !double.IsInfinity(x) && !double.IsNaN(x); + + public static double DoubleFromMantissaAndExponent(double x, int exp) => x * Math.Pow(2.0, exp); + + public static bool GreaterThan(double value1, double value2) => value1 > value2 && !AreClose(value1, value2); + + public static bool GreaterThanOrClose(double value1, double value2) + { + if (value1 <= value2) + { + return AreClose(value1, value2); + } + return true; + } + + public static double Hypotenuse(double x, double y) => Math.Sqrt(x * x + y * y); + + public static bool LessThan(double value1, double value2) => value1 < value2 && !AreClose(value1, value2); + + public static bool LessThanOrClose(double value1, double value2) + { + if (value1 >= value2) + { + return AreClose(value1, value2); + } + return true; + } + + public static double EnsureRange(double value, double? min, double? max) + { + if (min.HasValue && value < min.Value) + { + return min.Value; + } + if (max.HasValue && value > max.Value) + { + return max.Value; + } + return value; + } + + public static double SafeDivide(double lhs, double rhs, double fallback) + { + if (!IsVerySmall(rhs)) + { + return lhs / rhs; + } + return fallback; + } + } +} diff --git a/EleCho.WpfSuite/Themes/Generic.xaml b/EleCho.WpfSuite/Themes/Generic.xaml new file mode 100644 index 0000000000..8734c63c81 --- /dev/null +++ b/EleCho.WpfSuite/Themes/Generic.xaml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + diff --git a/EleCho.WpfSuite/Utilities/ScrollViewerUtils.cs b/EleCho.WpfSuite/Utilities/ScrollViewerUtils.cs new file mode 100644 index 0000000000..d204febb6c --- /dev/null +++ b/EleCho.WpfSuite/Utilities/ScrollViewerUtils.cs @@ -0,0 +1,120 @@ +using System; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; + +namespace EleCho.WpfSuite +{ + /// + /// ScrollViewer Utilities + /// + public static class ScrollViewerUtils + { + /// + /// Get value of VerticalOffset property + /// + /// + /// + public static double GetVerticalOffset(DependencyObject d) + { + if (d is ScrollViewer sv) + { + return sv.VerticalOffset; + } + else if (d is ScrollContentPresenter scp) + { + return scp.VerticalOffset; + } + + + return (double)d.GetValue(VerticalOffsetProperty); + } + + /// + /// Set value of VerticalOffset property + /// + /// + /// + public static void SetVerticalOffset(DependencyObject obj, double value) + { + obj.SetValue(VerticalOffsetProperty, value); + } + + /// + /// Get value of HorizontalOffset property + /// + /// + /// + public static double GetHorizontalOffset(DependencyObject d) + { + if (d is ScrollViewer sv) + { + return sv.HorizontalOffset; + } + else if (d is ScrollContentPresenter scp) + { + return scp.HorizontalOffset; + } + + return (double)d.GetValue(HorizontalOffsetProperty); + } + + /// + /// Set value of HorizontalOffset property + /// + /// + /// + public static void SetHorizontalOffset(DependencyObject obj, double value) + { + obj.SetValue(HorizontalOffsetProperty, value); + } + + + /// + /// The DependencyProperty of VerticalOffset property + /// + public static readonly DependencyProperty VerticalOffsetProperty = + DependencyProperty.RegisterAttached("VerticalOffset", typeof(double), typeof(ScrollViewerUtils), new PropertyMetadata(0.0, VerticalOffsetChangedCallback)); + + /// + /// The DependencyProperty of HorizontalOffset property + /// + public static readonly DependencyProperty HorizontalOffsetProperty = + DependencyProperty.RegisterAttached("HorizontalOffset", typeof(double), typeof(ScrollViewerUtils), new PropertyMetadata(0.0, HorizontalOffsetChangedCallback)); + + + private static void VerticalOffsetChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (e.NewValue is not double offset) + { + return; + } + + if (d is ScrollViewer sv) + { + sv.ScrollToVerticalOffset(offset); + } + else if (d is ScrollContentPresenter scp) + { + scp.SetVerticalOffset(offset); + } + } + + private static void HorizontalOffsetChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (e.NewValue is not double offset) + { + return; + } + + if (d is ScrollViewer sv) + { + sv.ScrollToHorizontalOffset(offset); + } + else if (d is ScrollContentPresenter scp) + { + scp.SetHorizontalOffset(offset); + } + } + } +} diff --git a/EleCho.WpfSuite/ValueConverters/FallbackConverter.cs b/EleCho.WpfSuite/ValueConverters/FallbackConverter.cs new file mode 100644 index 0000000000..6741b74616 --- /dev/null +++ b/EleCho.WpfSuite/ValueConverters/FallbackConverter.cs @@ -0,0 +1,26 @@ +using System; +using System.Globalization; +using System.Windows; + +namespace EleCho.WpfSuite +{ + /// + /// Fallback between multiple values, return the first non-null value + /// + public class FallbackConverter : SingletonMultiValueConverterBase + { + /// + public override object? Convert(object?[] values, Type targetType, object? parameter, CultureInfo culture) + { + foreach (var value in values) + { + if (value is not null && + value != DependencyProperty.UnsetValue) + return value; + } + + return null; + } + } +} + diff --git a/EleCho.WpfSuite/ValueConverters/MultiValueConverterBase.cs b/EleCho.WpfSuite/ValueConverters/MultiValueConverterBase.cs new file mode 100644 index 0000000000..72a9ebe049 --- /dev/null +++ b/EleCho.WpfSuite/ValueConverters/MultiValueConverterBase.cs @@ -0,0 +1,22 @@ +using System; +using System.Globalization; +using System.Windows.Data; + +namespace EleCho.WpfSuite +{ + /// + /// Base class of multi value converter + /// + /// + public abstract class MultiValueConverterBase : IMultiValueConverter + { + /// + public abstract object? Convert(object?[] values, Type targetType, object? parameter, CultureInfo culture); + + /// + public virtual object?[] ConvertBack(object? value, Type[] targetTypes, object? parameter, CultureInfo culture) + { + throw new NotSupportedException(); + } + } +} diff --git a/EleCho.WpfSuite/ValueConverters/SingletonMultiValueConverterBase.cs b/EleCho.WpfSuite/ValueConverters/SingletonMultiValueConverterBase.cs new file mode 100644 index 0000000000..538ea2f15d --- /dev/null +++ b/EleCho.WpfSuite/ValueConverters/SingletonMultiValueConverterBase.cs @@ -0,0 +1,17 @@ +namespace EleCho.WpfSuite +{ + /// + /// Base class of singleton multi value converter + /// + /// + public abstract class SingletonMultiValueConverterBase : MultiValueConverterBase + where TSelf : SingletonMultiValueConverterBase, new() + { + private static TSelf? _instance = null; + + /// + /// Get an instance of + /// + public static TSelf Instance => _instance ?? new(); + } +} diff --git a/ILSpy.sln b/ILSpy.sln index 604606ee37..8efa6d216d 100644 --- a/ILSpy.sln +++ b/ILSpy.sln @@ -36,7 +36,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ICSharpCode.Decompiler.Test EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ICSharpCode.ILSpyX", "ICSharpCode.ILSpyX\ICSharpCode.ILSpyX.csproj", "{F8EFCF9D-B9A3-4BA0-A1B2-B026A71DAC22}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.BamlDecompiler", "ICSharpCode.BamlDecompiler\ICSharpCode.BamlDecompiler.csproj", "{81A30182-3378-4952-8880-F44822390040}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ICSharpCode.BamlDecompiler", "ICSharpCode.BamlDecompiler\ICSharpCode.BamlDecompiler.csproj", "{81A30182-3378-4952-8880-F44822390040}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EleCho.WpfSuite", "EleCho.WpfSuite\EleCho.WpfSuite.csproj", "{486469B9-51AF-43D0-ABCE-F5FA7E5FBE4C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -100,6 +102,10 @@ Global {81A30182-3378-4952-8880-F44822390040}.Debug|Any CPU.Build.0 = Debug|Any CPU {81A30182-3378-4952-8880-F44822390040}.Release|Any CPU.ActiveCfg = Release|Any CPU {81A30182-3378-4952-8880-F44822390040}.Release|Any CPU.Build.0 = Release|Any CPU + {486469B9-51AF-43D0-ABCE-F5FA7E5FBE4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {486469B9-51AF-43D0-ABCE-F5FA7E5FBE4C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {486469B9-51AF-43D0-ABCE-F5FA7E5FBE4C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {486469B9-51AF-43D0-ABCE-F5FA7E5FBE4C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index c155a330fe..0b9d1dc040 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -45,7 +45,6 @@ - @@ -85,6 +84,7 @@ + diff --git a/SharpTreeView/ICSharpCode.TreeView.csproj b/SharpTreeView/ICSharpCode.TreeView.csproj index 1998b5c391..45eca3a621 100644 --- a/SharpTreeView/ICSharpCode.TreeView.csproj +++ b/SharpTreeView/ICSharpCode.TreeView.csproj @@ -22,8 +22,11 @@ - + + + + From 0360f8d6d971e71edd88ad1cdc75856f50675761 Mon Sep 17 00:00:00 2001 From: SlimeNull Date: Tue, 16 Jul 2024 09:14:21 +0800 Subject: [PATCH 3/7] Remove unnecessary parts from EleCho.WpfSuite --- EleCho.WpfSuite/Controls/Border.cs | 270 --------- EleCho.WpfSuite/Controls/ListBox.cs | 14 +- EleCho.WpfSuite/Controls/ListBoxItem.cs | 137 ----- .../Controls/ListBoxItemResources.xaml | 174 ------ .../Controls/ListBoxResources.xaml | 13 +- EleCho.WpfSuite/Controls/ListView.cs | 14 +- EleCho.WpfSuite/Controls/ListViewItem.cs | 136 ----- .../Controls/ListViewItemResources.xaml | 174 ------ .../Controls/ListViewResources.xaml | 13 +- EleCho.WpfSuite/Controls/RepeatButton.cs | 113 ---- .../Controls/RepeatButtonResources.xaml | 150 ----- EleCho.WpfSuite/Controls/ScrollBar.cs | 234 -------- .../Controls/ScrollBarResources.xaml | 514 ------------------ .../Controls/ScrollViewerResources.xaml | 34 -- EleCho.WpfSuite/Controls/Thumb.cs | 55 -- EleCho.WpfSuite/Controls/ThumbResources.xaml | 34 -- EleCho.WpfSuite/EleCho.WpfSuite.csproj | 16 - EleCho.WpfSuite/Themes/Generic.xaml | 11 +- ILSpy/App.xaml | 26 +- SharpTreeView/SharpTreeViewItem.cs | 2 +- 20 files changed, 17 insertions(+), 2117 deletions(-) delete mode 100644 EleCho.WpfSuite/Controls/Border.cs delete mode 100644 EleCho.WpfSuite/Controls/ListBoxItem.cs delete mode 100644 EleCho.WpfSuite/Controls/ListBoxItemResources.xaml delete mode 100644 EleCho.WpfSuite/Controls/ListViewItem.cs delete mode 100644 EleCho.WpfSuite/Controls/ListViewItemResources.xaml delete mode 100644 EleCho.WpfSuite/Controls/RepeatButton.cs delete mode 100644 EleCho.WpfSuite/Controls/RepeatButtonResources.xaml delete mode 100644 EleCho.WpfSuite/Controls/ScrollBar.cs delete mode 100644 EleCho.WpfSuite/Controls/ScrollBarResources.xaml delete mode 100644 EleCho.WpfSuite/Controls/ScrollViewerResources.xaml delete mode 100644 EleCho.WpfSuite/Controls/Thumb.cs delete mode 100644 EleCho.WpfSuite/Controls/ThumbResources.xaml diff --git a/EleCho.WpfSuite/Controls/Border.cs b/EleCho.WpfSuite/Controls/Border.cs deleted file mode 100644 index 18a333341a..0000000000 --- a/EleCho.WpfSuite/Controls/Border.cs +++ /dev/null @@ -1,270 +0,0 @@ -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; -using System.Windows.Media.Media3D; - -namespace EleCho.WpfSuite -{ - /// - public class Border : System.Windows.Controls.Border - { - /// - /// A geometry to clip the content of this border correctly - /// - public Geometry ContentClip - { - get { return (Geometry)GetValue(ContentClipProperty); } - set { SetValue(ContentClipProperty, value); } - } - - - /// - /// The key needed set a read-only property - /// - public static readonly DependencyPropertyKey ContentClipPropertyKey = - DependencyProperty.RegisterReadOnly(nameof(ContentClip), typeof(Geometry), typeof(Border), new PropertyMetadata(default(Geometry))); - - /// - /// The DependencyProperty for the ContentClip property.
- /// Flags: None
- /// Default value: null - ///
- public static readonly DependencyProperty ContentClipProperty = - ContentClipPropertyKey.DependencyProperty; - - private Geometry? CalculateContentClip() - { - var borderThickness = BorderThickness; - var cornerRadius = CornerRadius; - var renderSize = RenderSize; - - var contentWidth = renderSize.Width - borderThickness.Left - borderThickness.Right; - var contentHeight = renderSize.Height - borderThickness.Top - borderThickness.Bottom; - - if (contentWidth > 0 && contentHeight > 0) - { - var rect = new Rect(0, 0, contentWidth, contentHeight); - var radii = new Radii(cornerRadius, borderThickness, false); - - var contentGeometry = new StreamGeometry(); - using StreamGeometryContext ctx = contentGeometry.Open(); - GenerateGeometry(ctx, rect, radii); - - contentGeometry.Freeze(); - return contentGeometry; - - } - else - { - return null; - } - } - - /// - protected override void OnRender(DrawingContext dc) - { - SetValue(ContentClipPropertyKey, CalculateContentClip()); - base.OnRender(dc); - } - - /// - /// Generates a StreamGeometry. - /// - /// An already opened StreamGeometryContext. - /// Rectangle for geometry conversion. - /// Corner radii. - /// Result geometry. - private static void GenerateGeometry(StreamGeometryContext ctx, Rect rect, Radii radii) - { - // - // compute the coordinates of the key points - // - - Point topLeft = new Point(radii.LeftTop, 0); - Point topRight = new Point(rect.Width - radii.RightTop, 0); - Point rightTop = new Point(rect.Width, radii.TopRight); - Point rightBottom = new Point(rect.Width, rect.Height - radii.BottomRight); - Point bottomRight = new Point(rect.Width - radii.RightBottom, rect.Height); - Point bottomLeft = new Point(radii.LeftBottom, rect.Height); - Point leftBottom = new Point(0, rect.Height - radii.BottomLeft); - Point leftTop = new Point(0, radii.TopLeft); - - // - // check key points for overlap and resolve by partitioning radii according to - // the percentage of each one. - // - - // top edge is handled here - if (topLeft.X > topRight.X) - { - double v = (radii.LeftTop) / (radii.LeftTop + radii.RightTop) * rect.Width; - topLeft.X = v; - topRight.X = v; - } - - // right edge - if (rightTop.Y > rightBottom.Y) - { - double v = (radii.TopRight) / (radii.TopRight + radii.BottomRight) * rect.Height; - rightTop.Y = v; - rightBottom.Y = v; - } - - // bottom edge - if (bottomRight.X < bottomLeft.X) - { - double v = (radii.LeftBottom) / (radii.LeftBottom + radii.RightBottom) * rect.Width; - bottomRight.X = v; - bottomLeft.X = v; - } - - // left edge - if (leftBottom.Y < leftTop.Y) - { - double v = (radii.TopLeft) / (radii.TopLeft + radii.BottomLeft) * rect.Height; - leftBottom.Y = v; - leftTop.Y = v; - } - - // - // add on offsets - // - - Vector offset = new Vector(rect.TopLeft.X, rect.TopLeft.Y); - topLeft += offset; - topRight += offset; - rightTop += offset; - rightBottom += offset; - bottomRight += offset; - bottomLeft += offset; - leftBottom += offset; - leftTop += offset; - - // - // create the border geometry - // - ctx.BeginFigure(topLeft, true /* is filled */, true /* is closed */); - - // Top line - ctx.LineTo(topRight, true /* is stroked */, false /* is smooth join */); - - // Upper-right corner - double radiusX = rect.TopRight.X - topRight.X; - double radiusY = rightTop.Y - rect.TopRight.Y; - if (!MathHelper.IsZero(radiusX) - || !MathHelper.IsZero(radiusY)) - { - ctx.ArcTo(rightTop, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise, true, false); - } - - // Right line - ctx.LineTo(rightBottom, true /* is stroked */, false /* is smooth join */); - - // Lower-right corner - radiusX = rect.BottomRight.X - bottomRight.X; - radiusY = rect.BottomRight.Y - rightBottom.Y; - if (!MathHelper.IsZero(radiusX) - || !MathHelper.IsZero(radiusY)) - { - ctx.ArcTo(bottomRight, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise, true, false); - } - - // Bottom line - ctx.LineTo(bottomLeft, true /* is stroked */, false /* is smooth join */); - - // Lower-left corner - radiusX = bottomLeft.X - rect.BottomLeft.X; - radiusY = rect.BottomLeft.Y - leftBottom.Y; - if (!MathHelper.IsZero(radiusX) - || !MathHelper.IsZero(radiusY)) - { - ctx.ArcTo(leftBottom, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise, true, false); - } - - // Left line - ctx.LineTo(leftTop, true /* is stroked */, false /* is smooth join */); - - // Upper-left corner - radiusX = topLeft.X - rect.TopLeft.X; - radiusY = leftTop.Y - rect.TopLeft.Y; - if (!MathHelper.IsZero(radiusX) - || !MathHelper.IsZero(radiusY)) - { - ctx.ArcTo(topLeft, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise, true, false); - } - } - - - private struct Radii - { - internal Radii(CornerRadius radii, Thickness borders, bool outer) - { - double left = 0.5 * borders.Left; - double top = 0.5 * borders.Top; - double right = 0.5 * borders.Right; - double bottom = 0.5 * borders.Bottom; - - if (outer) - { - if (MathHelper.IsZero(radii.TopLeft)) - { - LeftTop = TopLeft = 0.0; - } - else - { - LeftTop = radii.TopLeft + left; - TopLeft = radii.TopLeft + top; - } - if (MathHelper.IsZero(radii.TopRight)) - { - TopRight = RightTop = 0.0; - } - else - { - TopRight = radii.TopRight + top; - RightTop = radii.TopRight + right; - } - if (MathHelper.IsZero(radii.BottomRight)) - { - RightBottom = BottomRight = 0.0; - } - else - { - RightBottom = radii.BottomRight + right; - BottomRight = radii.BottomRight + bottom; - } - if (MathHelper.IsZero(radii.BottomLeft)) - { - BottomLeft = LeftBottom = 0.0; - } - else - { - BottomLeft = radii.BottomLeft + bottom; - LeftBottom = radii.BottomLeft + left; - } - } - else - { - LeftTop = Math.Max(0.0, radii.TopLeft - left); - TopLeft = Math.Max(0.0, radii.TopLeft - top); - TopRight = Math.Max(0.0, radii.TopRight - top); - RightTop = Math.Max(0.0, radii.TopRight - right); - RightBottom = Math.Max(0.0, radii.BottomRight - right); - BottomRight = Math.Max(0.0, radii.BottomRight - bottom); - BottomLeft = Math.Max(0.0, radii.BottomLeft - bottom); - LeftBottom = Math.Max(0.0, radii.BottomLeft - left); - } - } - - internal double LeftTop; - internal double TopLeft; - internal double TopRight; - internal double RightTop; - internal double RightBottom; - internal double BottomRight; - internal double BottomLeft; - internal double LeftBottom; - } - } -} diff --git a/EleCho.WpfSuite/Controls/ListBox.cs b/EleCho.WpfSuite/Controls/ListBox.cs index a5aefb4153..8f53638219 100644 --- a/EleCho.WpfSuite/Controls/ListBox.cs +++ b/EleCho.WpfSuite/Controls/ListBox.cs @@ -51,23 +51,11 @@ public Brush DisabledBorderBrush set { SetValue(DisabledBorderBrushProperty, value); } } - /// - protected override DependencyObject GetContainerForItemOverride() - { - return new ListBoxItem(); - } - - /// - protected override bool IsItemItsOwnContainerOverride(object item) - { - return item is ListBoxItem; - } - /// /// DependencyProperty of property /// public static readonly DependencyProperty CornerRadiusProperty = - Border.CornerRadiusProperty.AddOwner(typeof(ListBox)); + System.Windows.Controls.Border.CornerRadiusProperty.AddOwner(typeof(ListBox)); /// /// The DependencyProperty of property diff --git a/EleCho.WpfSuite/Controls/ListBoxItem.cs b/EleCho.WpfSuite/Controls/ListBoxItem.cs deleted file mode 100644 index 2552d016f9..0000000000 --- a/EleCho.WpfSuite/Controls/ListBoxItem.cs +++ /dev/null @@ -1,137 +0,0 @@ -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; - -namespace EleCho.WpfSuite -{ - public class ListBoxItem : System.Windows.Controls.ListBoxItem - { - static ListBoxItem() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(ListBoxItem), new FrameworkPropertyMetadata(typeof(ListBoxItem))); - } - - /// - /// The CornerRadius property allows users to control the roundness of the corners independently by - /// setting a radius value for each corner. Radius values that are too large are scaled so that they - /// smoothly blend from corner to corner. - /// - public CornerRadius CornerRadius - { - get { return (CornerRadius)GetValue(CornerRadiusProperty); } - set { SetValue(CornerRadiusProperty, value); } - } - public Brush HoverForeground - { - get { return (Brush)GetValue(HoverForegroundProperty); } - set { SetValue(HoverForegroundProperty, value); } - } - - public Brush HoverBackground - { - get { return (Brush)GetValue(HoverBackgroundProperty); } - set { SetValue(HoverBackgroundProperty, value); } - } - - public Brush HoverBorderBrush - { - get { return (Brush)GetValue(HoverBorderBrushProperty); } - set { SetValue(HoverBorderBrushProperty, value); } - } - - public Brush SelectedForeground - { - get { return (Brush)GetValue(SelectedForegroundProperty); } - set { SetValue(SelectedForegroundProperty, value); } - } - - public Brush SelectedBackground - { - get { return (Brush)GetValue(SelectedBackgroundProperty); } - set { SetValue(SelectedBackgroundProperty, value); } - } - - public Brush SelectedBorderBrush - { - get { return (Brush)GetValue(SelectedBorderBrushProperty); } - set { SetValue(SelectedBorderBrushProperty, value); } - } - - public Brush SelectedActiveForeground - { - get { return (Brush)GetValue(SelectedActiveForegroundProperty); } - set { SetValue(SelectedActiveForegroundProperty, value); } - } - - public Brush SelectedActiveBackground - { - get { return (Brush)GetValue(SelectedActiveBackgroundProperty); } - set { SetValue(SelectedActiveBackgroundProperty, value); } - } - - public Brush SelectedActiveBorderBrush - { - get { return (Brush)GetValue(SelectedActiveBorderBrushProperty); } - set { SetValue(SelectedActiveBorderBrushProperty, value); } - } - - public Brush DisabledForeground - { - get { return (Brush)GetValue(DisabledForegroundProperty); } - set { SetValue(DisabledForegroundProperty, value); } - } - - public Brush DisabledBackground - { - get { return (Brush)GetValue(DisabledBackgroundProperty); } - set { SetValue(DisabledBackgroundProperty, value); } - } - - public Brush DisabledBorderBrush - { - get { return (Brush)GetValue(DisabledBorderBrushProperty); } - set { SetValue(DisabledBorderBrushProperty, value); } - } - - - public static readonly DependencyProperty CornerRadiusProperty = - Border.CornerRadiusProperty.AddOwner(typeof(ListBoxItem)); - - - public static readonly DependencyProperty HoverForegroundProperty = - DependencyProperty.Register(nameof(HoverForeground), typeof(Brush), typeof(ListBoxItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty HoverBackgroundProperty = - DependencyProperty.Register(nameof(HoverBackground), typeof(Brush), typeof(ListBoxItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty HoverBorderBrushProperty = - DependencyProperty.Register(nameof(HoverBorderBrush), typeof(Brush), typeof(ListBoxItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty SelectedForegroundProperty = - DependencyProperty.Register(nameof(SelectedForeground), typeof(Brush), typeof(ListBoxItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty SelectedBackgroundProperty = - DependencyProperty.Register(nameof(SelectedBackground), typeof(Brush), typeof(ListBoxItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty SelectedBorderBrushProperty = - DependencyProperty.Register(nameof(SelectedBorderBrush), typeof(Brush), typeof(ListBoxItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty SelectedActiveForegroundProperty = - DependencyProperty.Register(nameof(SelectedActiveForeground), typeof(Brush), typeof(ListBoxItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty SelectedActiveBackgroundProperty = - DependencyProperty.Register(nameof(SelectedActiveBackground), typeof(Brush), typeof(ListBoxItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty SelectedActiveBorderBrushProperty = - DependencyProperty.Register(nameof(SelectedActiveBorderBrush), typeof(Brush), typeof(ListBoxItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty DisabledForegroundProperty = - DependencyProperty.Register(nameof(DisabledForeground), typeof(Brush), typeof(ListBoxItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty DisabledBackgroundProperty = - DependencyProperty.Register(nameof(DisabledBackground), typeof(Brush), typeof(ListBoxItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty DisabledBorderBrushProperty = - DependencyProperty.Register(nameof(DisabledBorderBrush), typeof(Brush), typeof(ListBoxItem), new FrameworkPropertyMetadata(null)); - } -} diff --git a/EleCho.WpfSuite/Controls/ListBoxItemResources.xaml b/EleCho.WpfSuite/Controls/ListBoxItemResources.xaml deleted file mode 100644 index 80be07d2f9..0000000000 --- a/EleCho.WpfSuite/Controls/ListBoxItemResources.xaml +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/EleCho.WpfSuite/Controls/ListBoxResources.xaml b/EleCho.WpfSuite/Controls/ListBoxResources.xaml index 89e21560f8..b971ec6394 100644 --- a/EleCho.WpfSuite/Controls/ListBoxResources.xaml +++ b/EleCho.WpfSuite/Controls/ListBoxResources.xaml @@ -22,7 +22,7 @@ - - - - - - - + + + diff --git a/EleCho.WpfSuite/Controls/ListView.cs b/EleCho.WpfSuite/Controls/ListView.cs index fd9f8ea47f..f85699ccaa 100644 --- a/EleCho.WpfSuite/Controls/ListView.cs +++ b/EleCho.WpfSuite/Controls/ListView.cs @@ -41,24 +41,12 @@ public Brush DisabledBorderBrush set { SetValue(DisabledBorderBrushProperty, value); } } - /// - protected override DependencyObject GetContainerForItemOverride() - { - return new ListViewItem(); - } - - /// - protected override bool IsItemItsOwnContainerOverride(object item) - { - return item is ListViewItem; - } - /// /// DependencyProperty of property /// public static readonly DependencyProperty CornerRadiusProperty = - Border.CornerRadiusProperty.AddOwner(typeof(ListView)); + System.Windows.Controls.Border.CornerRadiusProperty.AddOwner(typeof(ListView)); /// /// The DependencyProperty of property diff --git a/EleCho.WpfSuite/Controls/ListViewItem.cs b/EleCho.WpfSuite/Controls/ListViewItem.cs deleted file mode 100644 index 669eedd82b..0000000000 --- a/EleCho.WpfSuite/Controls/ListViewItem.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System.Windows; -using System.Windows.Media; - -namespace EleCho.WpfSuite -{ - public class ListViewItem : System.Windows.Controls.ListViewItem - { - static ListViewItem() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(ListViewItem), new FrameworkPropertyMetadata(typeof(ListViewItem))); - } - - /// - /// The CornerRadius property allows users to control the roundness of the corners independently by - /// setting a radius value for each corner. Radius values that are too large are scaled so that they - /// smoothly blend from corner to corner. - /// - public CornerRadius CornerRadius - { - get { return (CornerRadius)GetValue(CornerRadiusProperty); } - set { SetValue(CornerRadiusProperty, value); } - } - public Brush HoverForeground - { - get { return (Brush)GetValue(HoverForegroundProperty); } - set { SetValue(HoverForegroundProperty, value); } - } - - public Brush HoverBackground - { - get { return (Brush)GetValue(HoverBackgroundProperty); } - set { SetValue(HoverBackgroundProperty, value); } - } - - public Brush HoverBorderBrush - { - get { return (Brush)GetValue(HoverBorderBrushProperty); } - set { SetValue(HoverBorderBrushProperty, value); } - } - - public Brush SelectedForeground - { - get { return (Brush)GetValue(SelectedForegroundProperty); } - set { SetValue(SelectedForegroundProperty, value); } - } - - public Brush SelectedBackground - { - get { return (Brush)GetValue(SelectedBackgroundProperty); } - set { SetValue(SelectedBackgroundProperty, value); } - } - - public Brush SelectedBorderBrush - { - get { return (Brush)GetValue(SelectedBorderBrushProperty); } - set { SetValue(SelectedBorderBrushProperty, value); } - } - - public Brush SelectedActiveForeground - { - get { return (Brush)GetValue(SelectedActiveForegroundProperty); } - set { SetValue(SelectedActiveForegroundProperty, value); } - } - - public Brush SelectedActiveBackground - { - get { return (Brush)GetValue(SelectedActiveBackgroundProperty); } - set { SetValue(SelectedActiveBackgroundProperty, value); } - } - - public Brush SelectedActiveBorderBrush - { - get { return (Brush)GetValue(SelectedActiveBorderBrushProperty); } - set { SetValue(SelectedActiveBorderBrushProperty, value); } - } - - public Brush DisabledForeground - { - get { return (Brush)GetValue(DisabledForegroundProperty); } - set { SetValue(DisabledForegroundProperty, value); } - } - - public Brush DisabledBackground - { - get { return (Brush)GetValue(DisabledBackgroundProperty); } - set { SetValue(DisabledBackgroundProperty, value); } - } - - public Brush DisabledBorderBrush - { - get { return (Brush)GetValue(DisabledBorderBrushProperty); } - set { SetValue(DisabledBorderBrushProperty, value); } - } - - - public static readonly DependencyProperty CornerRadiusProperty = - Border.CornerRadiusProperty.AddOwner(typeof(ListViewItem)); - - - public static readonly DependencyProperty HoverForegroundProperty = - DependencyProperty.Register(nameof(HoverForeground), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty HoverBackgroundProperty = - DependencyProperty.Register(nameof(HoverBackground), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty HoverBorderBrushProperty = - DependencyProperty.Register(nameof(HoverBorderBrush), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty SelectedForegroundProperty = - DependencyProperty.Register(nameof(SelectedForeground), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty SelectedBackgroundProperty = - DependencyProperty.Register(nameof(SelectedBackground), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty SelectedBorderBrushProperty = - DependencyProperty.Register(nameof(SelectedBorderBrush), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty SelectedActiveForegroundProperty = - DependencyProperty.Register(nameof(SelectedActiveForeground), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty SelectedActiveBackgroundProperty = - DependencyProperty.Register(nameof(SelectedActiveBackground), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty SelectedActiveBorderBrushProperty = - DependencyProperty.Register(nameof(SelectedActiveBorderBrush), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty DisabledForegroundProperty = - DependencyProperty.Register(nameof(DisabledForeground), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty DisabledBackgroundProperty = - DependencyProperty.Register(nameof(DisabledBackground), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty DisabledBorderBrushProperty = - DependencyProperty.Register(nameof(DisabledBorderBrush), typeof(Brush), typeof(ListViewItem), new FrameworkPropertyMetadata(null)); - } -} diff --git a/EleCho.WpfSuite/Controls/ListViewItemResources.xaml b/EleCho.WpfSuite/Controls/ListViewItemResources.xaml deleted file mode 100644 index 517ad8a834..0000000000 --- a/EleCho.WpfSuite/Controls/ListViewItemResources.xaml +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/EleCho.WpfSuite/Controls/ListViewResources.xaml b/EleCho.WpfSuite/Controls/ListViewResources.xaml index 9dcc36b27a..a13a101f3a 100644 --- a/EleCho.WpfSuite/Controls/ListViewResources.xaml +++ b/EleCho.WpfSuite/Controls/ListViewResources.xaml @@ -22,7 +22,7 @@ - - - - - - - + + + diff --git a/EleCho.WpfSuite/Controls/RepeatButton.cs b/EleCho.WpfSuite/Controls/RepeatButton.cs deleted file mode 100644 index cbae4199dc..0000000000 --- a/EleCho.WpfSuite/Controls/RepeatButton.cs +++ /dev/null @@ -1,113 +0,0 @@ -using System.Windows; -using System.Windows.Media; - -namespace EleCho.WpfSuite -{ - public class RepeatButton : System.Windows.Controls.Primitives.RepeatButton - { - static RepeatButton() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(RepeatButton), new FrameworkPropertyMetadata(typeof(RepeatButton))); - } - - public CornerRadius CornerRadius - { - get { return (CornerRadius)GetValue(CornerRadiusProperty); } - set { SetValue(CornerRadiusProperty, value); } - } - - public Brush HoverForeground - { - get { return (Brush)GetValue(HoverForegroundProperty); } - set { SetValue(HoverForegroundProperty, value); } - } - - public Brush HoverBackground - { - get { return (Brush)GetValue(HoverBackgroundProperty); } - set { SetValue(HoverBackgroundProperty, value); } - } - - public Brush HoverBorderBrush - { - get { return (Brush)GetValue(HoverBorderBrushProperty); } - set { SetValue(HoverBorderBrushProperty, value); } - } - - public Brush PressedForeground - { - get { return (Brush)GetValue(PressedForegroundProperty); } - set { SetValue(PressedForegroundProperty, value); } - } - - public Brush PressedBackground - { - get { return (Brush)GetValue(PressedBackgroundProperty); } - set { SetValue(PressedBackgroundProperty, value); } - } - - public Brush PressedBorderBrush - { - get { return (Brush)GetValue(PressedBorderBrushProperty); } - set { SetValue(PressedBorderBrushProperty, value); } - } - - public Brush DisabledForeground - { - get { return (Brush)GetValue(DisabledForegroundProperty); } - set { SetValue(DisabledForegroundProperty, value); } - } - - public Brush DisabledBackground - { - get { return (Brush)GetValue(DisabledBackgroundProperty); } - set { SetValue(DisabledBackgroundProperty, value); } - } - - public Brush DisabledBorderBrush - { - get { return (Brush)GetValue(DisabledBorderBrushProperty); } - set { SetValue(DisabledBorderBrushProperty, value); } - } - - public Brush HighlightBrush - { - get { return (Brush)GetValue(HighlightBrushProperty); } - set { SetValue(HighlightBrushProperty, value); } - } - - - public static readonly DependencyProperty CornerRadiusProperty = - Border.CornerRadiusProperty.AddOwner(typeof(RepeatButton)); - - public static readonly DependencyProperty HoverForegroundProperty = - DependencyProperty.Register(nameof(HoverForeground), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty HoverBackgroundProperty = - DependencyProperty.Register(nameof(HoverBackground), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty HoverBorderBrushProperty = - DependencyProperty.Register(nameof(HoverBorderBrush), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty PressedForegroundProperty = - DependencyProperty.Register(nameof(PressedForeground), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty PressedBackgroundProperty = - DependencyProperty.Register(nameof(PressedBackground), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty PressedBorderBrushProperty = - DependencyProperty.Register(nameof(PressedBorderBrush), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty DisabledForegroundProperty = - DependencyProperty.Register(nameof(DisabledForeground), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty DisabledBackgroundProperty = - DependencyProperty.Register(nameof(DisabledBackground), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty DisabledBorderBrushProperty = - DependencyProperty.Register(nameof(DisabledBorderBrush), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty HighlightBrushProperty = - DependencyProperty.Register(nameof(HighlightBrush), typeof(Brush), typeof(RepeatButton), new FrameworkPropertyMetadata(SystemColors.HighlightBrush)); - } -} diff --git a/EleCho.WpfSuite/Controls/RepeatButtonResources.xaml b/EleCho.WpfSuite/Controls/RepeatButtonResources.xaml deleted file mode 100644 index 97495d7179..0000000000 --- a/EleCho.WpfSuite/Controls/RepeatButtonResources.xaml +++ /dev/null @@ -1,150 +0,0 @@ - - - - - \ No newline at end of file diff --git a/EleCho.WpfSuite/Controls/ScrollBar.cs b/EleCho.WpfSuite/Controls/ScrollBar.cs deleted file mode 100644 index e4d420cca5..0000000000 --- a/EleCho.WpfSuite/Controls/ScrollBar.cs +++ /dev/null @@ -1,234 +0,0 @@ -using System.Windows; -using System.Windows.Media; - -namespace EleCho.WpfSuite -{ - public class ScrollBar : System.Windows.Controls.Primitives.ScrollBar - { - private static readonly Brush s_thumbBrush =new SolidColorBrush(Color.FromRgb(205, 205, 205)); - private static readonly Brush s_glyphBrush= new SolidColorBrush(Color.FromRgb(96, 96, 96)); - private static readonly Brush s_disabledGlyphBrush =new SolidColorBrush(Color.FromRgb(112, 112, 112)); - private static readonly Geometry s_glyphLeft = Geometry.Parse("M 3.18,7 C3.18,7 5,7 5,7 5,7 1.81,3.5 1.81,3.5 1.81,3.5 5,0 5,0 5,0 3.18,0 3.18,0 3.18,0 0,3.5 0,3.5 0,3.5 3.18,7 3.18,7 z"); - private static readonly Geometry s_glyphRight = Geometry.Parse("M 1.81,7 C1.81,7 0,7 0,7 0,7 3.18,3.5 3.18,3.5 3.18,3.5 0,0 0,0 0,0 1.81,0 1.81,0 1.81,0 5,3.5 5,3.5 5,3.5 1.81,7 1.81,7 z"); - private static readonly Geometry s_glyphUp = Geometry.Parse("M 0,4 C0,4 0,6 0,6 0,6 3.5,2.5 3.5,2.5 3.5,2.5 7,6 7,6 7,6 7,4 7,4 7,4 3.5,0.5 3.5,0.5 3.5,0.5 0,4 0,4 z"); - private static readonly Geometry s_glyphDown = Geometry.Parse("M 0,2.5 C0,2.5 0,0.5 0,0.5 0,0.5 3.5,4 3.5,4 3.5,4 7,0.5 7,0.5 7,0.5 7,2.5 7,2.5 7,2.5 3.5,6 3.5,6 3.5,6 0,2.5 0,2.5 z"); - - static ScrollBar() - { - s_thumbBrush.Freeze(); - s_glyphBrush.Freeze(); - s_disabledGlyphBrush.Freeze(); - - s_glyphLeft.Freeze(); - s_glyphRight.Freeze(); - s_glyphUp.Freeze(); - s_glyphDown.Freeze(); - - DefaultStyleKeyProperty.OverrideMetadata(typeof(ScrollBar), new FrameworkPropertyMetadata(typeof(ScrollBar))); - } - - - public CornerRadius CornerRadius - { - get { return (CornerRadius)GetValue(CornerRadiusProperty); } - set { SetValue(CornerRadiusProperty, value); } - } - - public CornerRadius ThumbCornerRadius - { - get { return (CornerRadius)GetValue(ThumbCornerRadiusProperty); } - set { SetValue(ThumbCornerRadiusProperty, value); } - } - - public CornerRadius ButtonCornerRadius - { - get { return (CornerRadius)GetValue(ButtonCornerRadiusProperty); } - set { SetValue(ButtonCornerRadiusProperty, value); } - } - - public Thickness GlyphMargin - { - get { return (Thickness)GetValue(GlyphMarginProperty); } - set { SetValue(GlyphMarginProperty, value); } - } - - - - public Geometry? ArrowLeftGlyph - { - get { return (Geometry?)GetValue(ArrowLeftGlyphProperty); } - set { SetValue(ArrowLeftGlyphProperty, value); } - } - - public Geometry? ArrowRightGlyph - { - get { return (Geometry?)GetValue(ArrowRightGlyphProperty); } - set { SetValue(ArrowRightGlyphProperty, value); } - } - - public Geometry? ArrowUpGlyph - { - get { return (Geometry?)GetValue(ArrowUpGlyphProperty); } - set { SetValue(ArrowUpGlyphProperty, value); } - } - - public Geometry? ArrowDownGlyph - { - get { return (Geometry?)GetValue(ArrowDownGlyphProperty); } - set { SetValue(ArrowDownGlyphProperty, value); } - } - - public Brush ThumbBrush - { - get { return (Brush)GetValue(ThumbBrushProperty); } - set { SetValue(ThumbBrushProperty, value); } - } - - public Brush GlyphBrush - { - get { return (Brush)GetValue(GlyphBrushProperty); } - set { SetValue(GlyphBrushProperty, value); } - } - - public Brush HoverBackground - { - get { return (Brush)GetValue(HoverBackgroundProperty); } - set { SetValue(HoverBackgroundProperty, value); } - } - - public Brush HoverBorderBrush - { - get { return (Brush)GetValue(HoverBorderBrushProperty); } - set { SetValue(HoverBorderBrushProperty, value); } - } - - public Brush HoverThumbBrush - { - get { return (Brush)GetValue(HoverThumbBrushProperty); } - set { SetValue(HoverThumbBrushProperty, value); } - } - - public Brush HoverGlyphBrush - { - get { return (Brush)GetValue(HoverGlyphBrushProperty); } - set { SetValue(HoverGlyphBrushProperty, value); } - } - - public Brush PressedBackground - { - get { return (Brush)GetValue(PressedBackgroundProperty); } - set { SetValue(PressedBackgroundProperty, value); } - } - - public Brush PressedBorderBrush - { - get { return (Brush)GetValue(PressedBorderBrushProperty); } - set { SetValue(PressedBorderBrushProperty, value); } - } - - public Brush PressedThumbBrush - { - get { return (Brush)GetValue(PressedThumbBrushProperty); } - set { SetValue(PressedThumbBrushProperty, value); } - } - - public Brush PressedGlyphBrush - { - get { return (Brush)GetValue(PressedGlyphBrushProperty); } - set { SetValue(PressedGlyphBrushProperty, value); } - } - - public Brush DisabledBackground - { - get { return (Brush)GetValue(DisabledBackgroundProperty); } - set { SetValue(DisabledBackgroundProperty, value); } - } - - public Brush DisabledBorderBrush - { - get { return (Brush)GetValue(DisabledBorderBrushProperty); } - set { SetValue(DisabledBorderBrushProperty, value); } - } - - public Brush DisabledThumbBrush - { - get { return (Brush)GetValue(DisabledThumbBrushProperty); } - set { SetValue(DisabledThumbBrushProperty, value); } - } - - public Brush DisabledGlyphBrush - { - get { return (Brush)GetValue(DisabledGlyphBrushProperty); } - set { SetValue(DisabledGlyphBrushProperty, value); } - } - - - - - public static readonly DependencyProperty CornerRadiusProperty = - Border.CornerRadiusProperty.AddOwner(typeof(ScrollBar)); - - public static readonly DependencyProperty ThumbCornerRadiusProperty = - DependencyProperty.Register(nameof(ThumbCornerRadius), typeof(CornerRadius), typeof(ScrollBar), new FrameworkPropertyMetadata(new CornerRadius(0))); - - public static readonly DependencyProperty ButtonCornerRadiusProperty = - DependencyProperty.Register(nameof(ButtonCornerRadius), typeof(CornerRadius), typeof(ScrollBar), new FrameworkPropertyMetadata(new CornerRadius(0))); - - public static readonly DependencyProperty GlyphMarginProperty = - DependencyProperty.Register(nameof(GlyphMargin), typeof(Thickness), typeof(ScrollBar), new FrameworkPropertyMetadata(new Thickness(3))); - - public static readonly DependencyProperty ArrowLeftGlyphProperty = - DependencyProperty.Register(nameof(ArrowLeftGlyph), typeof(Geometry), typeof(ScrollBar), new FrameworkPropertyMetadata(s_glyphLeft)); - - public static readonly DependencyProperty ArrowRightGlyphProperty = - DependencyProperty.Register(nameof(ArrowRightGlyph), typeof(Geometry), typeof(ScrollBar), new FrameworkPropertyMetadata(s_glyphRight)); - - public static readonly DependencyProperty ArrowUpGlyphProperty = - DependencyProperty.Register(nameof(ArrowUpGlyph), typeof(Geometry), typeof(ScrollBar), new FrameworkPropertyMetadata(s_glyphUp)); - - public static readonly DependencyProperty ArrowDownGlyphProperty = - DependencyProperty.Register(nameof(ArrowDownGlyph), typeof(Geometry), typeof(ScrollBar), new FrameworkPropertyMetadata(s_glyphDown)); - - public static readonly DependencyProperty ThumbBrushProperty = - DependencyProperty.Register(nameof(ThumbBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(s_thumbBrush)); - - public static readonly DependencyProperty GlyphBrushProperty = - DependencyProperty.Register(nameof(GlyphBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(s_glyphBrush)); - - public static readonly DependencyProperty HoverBackgroundProperty = - DependencyProperty.Register(nameof(HoverBackground), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty HoverBorderBrushProperty = - DependencyProperty.Register(nameof(HoverBorderBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty HoverThumbBrushProperty = - DependencyProperty.Register(nameof(HoverThumbBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty HoverGlyphBrushProperty = - DependencyProperty.Register(nameof(HoverGlyphBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty PressedBackgroundProperty = - DependencyProperty.Register(nameof(PressedBackground), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty PressedBorderBrushProperty = - DependencyProperty.Register(nameof(PressedBorderBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty PressedThumbBrushProperty = - DependencyProperty.Register(nameof(PressedThumbBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty PressedGlyphBrushProperty = - DependencyProperty.Register(nameof(PressedGlyphBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty DisabledBackgroundProperty = - DependencyProperty.Register(nameof(DisabledBackground), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty DisabledBorderBrushProperty = - DependencyProperty.Register(nameof(DisabledBorderBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty DisabledThumbBrushProperty = - DependencyProperty.Register(nameof(DisabledThumbBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty DisabledGlyphBrushProperty = - DependencyProperty.Register(nameof(DisabledGlyphBrush), typeof(Brush), typeof(ScrollBar), new FrameworkPropertyMetadata(s_disabledGlyphBrush)); - } -} diff --git a/EleCho.WpfSuite/Controls/ScrollBarResources.xaml b/EleCho.WpfSuite/Controls/ScrollBarResources.xaml deleted file mode 100644 index c4dab43ba1..0000000000 --- a/EleCho.WpfSuite/Controls/ScrollBarResources.xaml +++ /dev/null @@ -1,514 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/EleCho.WpfSuite/Controls/ScrollViewerResources.xaml b/EleCho.WpfSuite/Controls/ScrollViewerResources.xaml deleted file mode 100644 index 68eef04cd0..0000000000 --- a/EleCho.WpfSuite/Controls/ScrollViewerResources.xaml +++ /dev/null @@ -1,34 +0,0 @@ - - - - \ No newline at end of file diff --git a/EleCho.WpfSuite/Controls/Thumb.cs b/EleCho.WpfSuite/Controls/Thumb.cs deleted file mode 100644 index 9580b3ce22..0000000000 --- a/EleCho.WpfSuite/Controls/Thumb.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Windows; -using System.Windows.Media; - -namespace EleCho.WpfSuite -{ - public class Thumb : System.Windows.Controls.Primitives.Thumb - { - static Thumb() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(Thumb), new FrameworkPropertyMetadata(typeof(Thumb))); - } - - /// - /// The CornerRadius property allows users to control the roundness of the corners independently by - /// setting a radius value for each corner. Radius values that are too large are scaled so that they - /// smoothly blend from corner to corner. - /// - public CornerRadius CornerRadius - { - get { return (CornerRadius)GetValue(CornerRadiusProperty); } - set { SetValue(CornerRadiusProperty, value); } - } - - public Brush HoverBackground - { - get { return (Brush)GetValue(HoverBackgroundProperty); } - set { SetValue(HoverBackgroundProperty, value); } - } - - public Brush PressedBackground - { - get { return (Brush)GetValue(PressedBackgroundProperty); } - set { SetValue(PressedBackgroundProperty, value); } - } - - public Brush DisabledBackground - { - get { return (Brush)GetValue(DisabledBackgroundProperty); } - set { SetValue(DisabledBackgroundProperty, value); } - } - - - public static readonly DependencyProperty CornerRadiusProperty = - Border.CornerRadiusProperty.AddOwner(typeof(Thumb)); - - public static readonly DependencyProperty HoverBackgroundProperty = - DependencyProperty.Register(nameof(HoverBackground), typeof(Brush), typeof(Thumb), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty PressedBackgroundProperty = - DependencyProperty.Register(nameof(PressedBackground), typeof(Brush), typeof(Thumb), new FrameworkPropertyMetadata(null)); - - public static readonly DependencyProperty DisabledBackgroundProperty = - DependencyProperty.Register(nameof(DisabledBackground), typeof(Brush), typeof(Thumb), new FrameworkPropertyMetadata(null)); - } -} diff --git a/EleCho.WpfSuite/Controls/ThumbResources.xaml b/EleCho.WpfSuite/Controls/ThumbResources.xaml deleted file mode 100644 index 564d5ba5cc..0000000000 --- a/EleCho.WpfSuite/Controls/ThumbResources.xaml +++ /dev/null @@ -1,34 +0,0 @@ - - - - \ No newline at end of file diff --git a/EleCho.WpfSuite/EleCho.WpfSuite.csproj b/EleCho.WpfSuite/EleCho.WpfSuite.csproj index 920f6a9b19..1278187f88 100644 --- a/EleCho.WpfSuite/EleCho.WpfSuite.csproj +++ b/EleCho.WpfSuite/EleCho.WpfSuite.csproj @@ -33,43 +33,27 @@ - - - - - - - - MSBuild:Compile - MSBuild:Compile - - - - - MSBuild:Compile - - diff --git a/EleCho.WpfSuite/Themes/Generic.xaml b/EleCho.WpfSuite/Themes/Generic.xaml index 8734c63c81..6b82c08468 100644 --- a/EleCho.WpfSuite/Themes/Generic.xaml +++ b/EleCho.WpfSuite/Themes/Generic.xaml @@ -1,14 +1,7 @@ - - - + - - - - - - + diff --git a/ILSpy/App.xaml b/ILSpy/App.xaml index 62f880e7b6..758a7ecb8d 100644 --- a/ILSpy/App.xaml +++ b/ILSpy/App.xaml @@ -5,7 +5,6 @@ xmlns:toms="urn:TomsToolbox" xmlns:ilSpy="clr-namespace:ICSharpCode.ILSpy" xmlns:themes="clr-namespace:ICSharpCode.ILSpy.Themes" - xmlns:ws="https://schemas.elecho.dev/wpfsuite" StartupUri="MainWindow.xaml"> - - - - + \ No newline at end of file diff --git a/SharpTreeView/SharpTreeViewItem.cs b/SharpTreeView/SharpTreeViewItem.cs index 21ac0c3e6e..6785b1f852 100644 --- a/SharpTreeView/SharpTreeViewItem.cs +++ b/SharpTreeView/SharpTreeViewItem.cs @@ -24,7 +24,7 @@ namespace ICSharpCode.TreeView { - public class SharpTreeViewItem : EleCho.WpfSuite.ListViewItem + public class SharpTreeViewItem : ListViewItem { static SharpTreeViewItem() { From 8179722d0192a53d72a77d52268ec1880ce5fc0c Mon Sep 17 00:00:00 2001 From: SlimeNull Date: Mon, 22 Jul 2024 16:11:16 +0800 Subject: [PATCH 4/7] Fix Format --- EleCho.WpfSuite/Controls/ListBox.cs | 95 +- .../Controls/ListBoxResources.xaml | 16 +- EleCho.WpfSuite/Controls/ListView.cs | 107 ++- .../Controls/ListViewResources.xaml | 16 +- EleCho.WpfSuite/Controls/ScrollViewer.cs | 848 +++++++++--------- EleCho.WpfSuite/MathHelper.cs | 102 +-- EleCho.WpfSuite/Themes/Generic.xaml | 8 +- .../Utilities/ScrollViewerUtils.cs | 196 ++-- .../ValueConverters/FallbackConverter.cs | 34 +- .../MultiValueConverterBase.cs | 28 +- .../SingletonMultiValueConverterBase.cs | 26 +- 11 files changed, 730 insertions(+), 746 deletions(-) diff --git a/EleCho.WpfSuite/Controls/ListBox.cs b/EleCho.WpfSuite/Controls/ListBox.cs index 8f53638219..633d01a12b 100644 --- a/EleCho.WpfSuite/Controls/ListBox.cs +++ b/EleCho.WpfSuite/Controls/ListBox.cs @@ -14,59 +14,56 @@ namespace EleCho.WpfSuite { - /// - public class ListBox : System.Windows.Controls.ListBox - { - static ListBox() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(ListBox), new FrameworkPropertyMetadata(typeof(ListBox))); - } + /// + public class ListBox : System.Windows.Controls.ListBox + { + static ListBox() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ListBox), new FrameworkPropertyMetadata(typeof(ListBox))); + } - /// - /// The CornerRadius property allows users to control the roundness of the corners independently by - /// setting a radius value for each corner. Radius values that are too large are scaled so that they - /// smoothly blend from corner to corner. - /// - public CornerRadius CornerRadius - { - get { return (CornerRadius)GetValue(CornerRadiusProperty); } - set { SetValue(CornerRadiusProperty, value); } - } + /// + /// The CornerRadius property allows users to control the roundness of the corners independently by + /// setting a radius value for each corner. Radius values that are too large are scaled so that they + /// smoothly blend from corner to corner. + /// + public CornerRadius CornerRadius { + get { return (CornerRadius)GetValue(CornerRadiusProperty); } + set { SetValue(CornerRadiusProperty, value); } + } - /// - /// Background when disabled - /// - public Brush DisabledBackground - { - get { return (Brush)GetValue(DisabledBackgroundProperty); } - set { SetValue(DisabledBackgroundProperty, value); } - } + /// + /// Background when disabled + /// + public Brush DisabledBackground { + get { return (Brush)GetValue(DisabledBackgroundProperty); } + set { SetValue(DisabledBackgroundProperty, value); } + } - /// - /// BorderBrush when pressed by mouse - /// - public Brush DisabledBorderBrush - { - get { return (Brush)GetValue(DisabledBorderBrushProperty); } - set { SetValue(DisabledBorderBrushProperty, value); } - } + /// + /// BorderBrush when pressed by mouse + /// + public Brush DisabledBorderBrush { + get { return (Brush)GetValue(DisabledBorderBrushProperty); } + set { SetValue(DisabledBorderBrushProperty, value); } + } - /// - /// DependencyProperty of property - /// - public static readonly DependencyProperty CornerRadiusProperty = - System.Windows.Controls.Border.CornerRadiusProperty.AddOwner(typeof(ListBox)); + /// + /// DependencyProperty of property + /// + public static readonly DependencyProperty CornerRadiusProperty = + System.Windows.Controls.Border.CornerRadiusProperty.AddOwner(typeof(ListBox)); - /// - /// The DependencyProperty of property - /// - public static readonly DependencyProperty DisabledBackgroundProperty = - DependencyProperty.Register(nameof(DisabledBackground), typeof(Brush), typeof(ListBox), new FrameworkPropertyMetadata(null)); + /// + /// The DependencyProperty of property + /// + public static readonly DependencyProperty DisabledBackgroundProperty = + DependencyProperty.Register(nameof(DisabledBackground), typeof(Brush), typeof(ListBox), new FrameworkPropertyMetadata(null)); - /// - /// The DependencyProperty of property - /// - public static readonly DependencyProperty DisabledBorderBrushProperty = - DependencyProperty.Register(nameof(DisabledBorderBrush), typeof(Brush), typeof(ListBox), new FrameworkPropertyMetadata(null)); - } + /// + /// The DependencyProperty of property + /// + public static readonly DependencyProperty DisabledBorderBrushProperty = + DependencyProperty.Register(nameof(DisabledBorderBrush), typeof(Brush), typeof(ListBox), new FrameworkPropertyMetadata(null)); + } } diff --git a/EleCho.WpfSuite/Controls/ListBoxResources.xaml b/EleCho.WpfSuite/Controls/ListBoxResources.xaml index b971ec6394..980580efbe 100644 --- a/EleCho.WpfSuite/Controls/ListBoxResources.xaml +++ b/EleCho.WpfSuite/Controls/ListBoxResources.xaml @@ -23,19 +23,19 @@ + Background="{TemplateBinding Background}" + BorderBrush="{TemplateBinding BorderBrush}" + BorderThickness="{TemplateBinding BorderThickness}" + CornerRadius="{TemplateBinding CornerRadius}" + Padding="1" + SnapsToDevicePixels="true"> - - + + diff --git a/EleCho.WpfSuite/Controls/ListView.cs b/EleCho.WpfSuite/Controls/ListView.cs index f85699ccaa..cb9756d2d9 100644 --- a/EleCho.WpfSuite/Controls/ListView.cs +++ b/EleCho.WpfSuite/Controls/ListView.cs @@ -3,61 +3,58 @@ namespace EleCho.WpfSuite { - /// - public class ListView : System.Windows.Controls.ListView - { - static ListView() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(ListView), new FrameworkPropertyMetadata(typeof(ListView))); - } - - - /// - /// The CornerRadius property allows users to control the roundness of the corners independently by - /// setting a radius value for each corner. Radius values that are too large are scaled so that they - /// smoothly blend from corner to corner. - /// - public CornerRadius CornerRadius - { - get { return (CornerRadius)GetValue(CornerRadiusProperty); } - set { SetValue(CornerRadiusProperty, value); } - } - - /// - /// Background when disabled - /// - public Brush DisabledBackground - { - get { return (Brush)GetValue(DisabledBackgroundProperty); } - set { SetValue(DisabledBackgroundProperty, value); } - } - - /// - /// BorderBrush when pressed by mouse - /// - public Brush DisabledBorderBrush - { - get { return (Brush)GetValue(DisabledBorderBrushProperty); } - set { SetValue(DisabledBorderBrushProperty, value); } - } - - - /// - /// DependencyProperty of property - /// - public static readonly DependencyProperty CornerRadiusProperty = + /// + public class ListView : System.Windows.Controls.ListView + { + static ListView() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ListView), new FrameworkPropertyMetadata(typeof(ListView))); + } + + + /// + /// The CornerRadius property allows users to control the roundness of the corners independently by + /// setting a radius value for each corner. Radius values that are too large are scaled so that they + /// smoothly blend from corner to corner. + /// + public CornerRadius CornerRadius { + get { return (CornerRadius)GetValue(CornerRadiusProperty); } + set { SetValue(CornerRadiusProperty, value); } + } + + /// + /// Background when disabled + /// + public Brush DisabledBackground { + get { return (Brush)GetValue(DisabledBackgroundProperty); } + set { SetValue(DisabledBackgroundProperty, value); } + } + + /// + /// BorderBrush when pressed by mouse + /// + public Brush DisabledBorderBrush { + get { return (Brush)GetValue(DisabledBorderBrushProperty); } + set { SetValue(DisabledBorderBrushProperty, value); } + } + + + /// + /// DependencyProperty of property + /// + public static readonly DependencyProperty CornerRadiusProperty = System.Windows.Controls.Border.CornerRadiusProperty.AddOwner(typeof(ListView)); - /// - /// The DependencyProperty of property - /// - public static readonly DependencyProperty DisabledBackgroundProperty = - DependencyProperty.Register(nameof(DisabledBackground), typeof(Brush), typeof(ListView), new FrameworkPropertyMetadata(null)); - - /// - /// The DependencyProperty of property - /// - public static readonly DependencyProperty DisabledBorderBrushProperty = - DependencyProperty.Register(nameof(DisabledBorderBrush), typeof(Brush), typeof(ListView), new FrameworkPropertyMetadata(null)); - } + /// + /// The DependencyProperty of property + /// + public static readonly DependencyProperty DisabledBackgroundProperty = + DependencyProperty.Register(nameof(DisabledBackground), typeof(Brush), typeof(ListView), new FrameworkPropertyMetadata(null)); + + /// + /// The DependencyProperty of property + /// + public static readonly DependencyProperty DisabledBorderBrushProperty = + DependencyProperty.Register(nameof(DisabledBorderBrush), typeof(Brush), typeof(ListView), new FrameworkPropertyMetadata(null)); + } } diff --git a/EleCho.WpfSuite/Controls/ListViewResources.xaml b/EleCho.WpfSuite/Controls/ListViewResources.xaml index a13a101f3a..b55d9454b3 100644 --- a/EleCho.WpfSuite/Controls/ListViewResources.xaml +++ b/EleCho.WpfSuite/Controls/ListViewResources.xaml @@ -23,19 +23,19 @@ + Background="{TemplateBinding Background}" + BorderBrush="{TemplateBinding BorderBrush}" + BorderThickness="{TemplateBinding BorderThickness}" + CornerRadius="{TemplateBinding CornerRadius}" + Padding="1" + SnapsToDevicePixels="true"> - - + + diff --git a/EleCho.WpfSuite/Controls/ScrollViewer.cs b/EleCho.WpfSuite/Controls/ScrollViewer.cs index 82b9d7b1af..ca0c820dbc 100644 --- a/EleCho.WpfSuite/Controls/ScrollViewer.cs +++ b/EleCho.WpfSuite/Controls/ScrollViewer.cs @@ -20,437 +20,427 @@ namespace EleCho.WpfSuite { - /// - public class ScrollViewer : System.Windows.Controls.ScrollViewer - { - static ScrollViewer() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(ScrollViewer), new FrameworkPropertyMetadata(typeof(ScrollViewer))); + /// + public class ScrollViewer : System.Windows.Controls.ScrollViewer + { + static ScrollViewer() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ScrollViewer), new FrameworkPropertyMetadata(typeof(ScrollViewer))); #if NETCOREAPP - _propertyHandlesMouseWheelScrollingGetter = typeof(ScrollViewer) - .GetProperty("HandlesMouseWheelScrolling", BindingFlags.Instance | BindingFlags.NonPublic)! - .GetGetMethod(true)! - .CreateDelegate(); + _propertyHandlesMouseWheelScrollingGetter = typeof(ScrollViewer) + .GetProperty("HandlesMouseWheelScrolling", BindingFlags.Instance | BindingFlags.NonPublic)! + .GetGetMethod(true)! + .CreateDelegate(); #else - _propertyHandlesMouseWheelScrollingGetter = (GetBool)typeof(ScrollViewer) - .GetProperty("HandlesMouseWheelScrolling", BindingFlags.Instance | BindingFlags.NonPublic)! - .GetGetMethod(true)! - .CreateDelegate(typeof(GetBool)); + _propertyHandlesMouseWheelScrollingGetter = (GetBool)typeof(ScrollViewer) + .GetProperty("HandlesMouseWheelScrolling", BindingFlags.Instance | BindingFlags.NonPublic)! + .GetGetMethod(true)! + .CreateDelegate(typeof(GetBool)); #endif - } - - private delegate bool GetBool(ScrollViewer scrollViewer); - private static readonly GetBool _propertyHandlesMouseWheelScrollingGetter; - private static readonly IEasingFunction _scrollingAnimationEase = new CubicEase(){ EasingMode = EasingMode.EaseOut }; - private const long _millisecondsBetweenTouchpadScrolling = 100; - - private bool _animationRunning = false; - private int _lastScrollDelta = 0; - private int _lastVerticalScrollingDelta = 0; - private int _lastHorizontalScrollingDelta = 0; - private long _lastScrollingTick; - - private FrameworkElement? _scrollContentPresenter; - - /// - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - _scrollContentPresenter = GetTemplateChild("PART_ScrollContentPresenter") as FrameworkElement; - } - - private void CoreScrollWithWheelDelta(MouseWheelEventArgs e) - { - if (e.Handled) - { - return; - } - - if (!AlwaysHandleMouseWheelScrolling && - !_propertyHandlesMouseWheelScrollingGetter.Invoke(this)) - { - return; - } - - bool vertical = ExtentHeight > 0; - bool horizontal = ExtentWidth > 0; - - var tickCount = Environment.TickCount; - var isTouchpadScrolling = - e.Delta % Mouse.MouseWheelDeltaForOneLine != 0 || - (tickCount - _lastScrollingTick < _millisecondsBetweenTouchpadScrolling && _lastScrollDelta % Mouse.MouseWheelDeltaForOneLine != 0); - - double scrollDelta = e.Delta; - - if (isTouchpadScrolling) - { - // touchpad 应该滚动更慢一些, 所以这里预先除以一个合适的值 - scrollDelta /= 2; - - // - scrollDelta *= TouchpadScrollDeltaFactor; - } - else - { - scrollDelta *= MouseScrollDeltaFactor; - } - - if (vertical) - { - if (ScrollInfo is IScrollInfo scrollInfo) - { - // 考虑到 VirtualizingPanel 可能是虚拟的大小, 所以这里需要校正 Delta - scrollDelta *= scrollInfo.ViewportHeight / (_scrollContentPresenter?.ActualHeight ?? ActualHeight); - } - - var sameDirectionAsLast = Math.Sign(e.Delta) == Math.Sign(_lastVerticalScrollingDelta); - var nowOffset = sameDirectionAsLast && _animationRunning ? VerticalOffsetTarget : VerticalOffset; - var newOffset = nowOffset - scrollDelta; - - if (newOffset < 0) - newOffset = 0; - if (newOffset > ScrollableHeight) - newOffset = ScrollableHeight; - - SetValue(VerticalOffsetTargetPropertyKey, newOffset); - BeginAnimation(ScrollViewerUtils.VerticalOffsetProperty, null); - - if (!EnableScrollingAnimation || isTouchpadScrolling) - { - ScrollToVerticalOffset(newOffset); - } - else - { - var diff = newOffset - VerticalOffset; - var absDiff = Math.Abs(diff); - var duration = ScrollingAnimationDuration; - if (absDiff < Mouse.MouseWheelDeltaForOneLine) - { - duration = new Duration(TimeSpan.FromTicks((long)(duration.TimeSpan.Ticks * absDiff / Mouse.MouseWheelDeltaForOneLine))); - } - - DoubleAnimation doubleAnimation = new DoubleAnimation() - { - EasingFunction = _scrollingAnimationEase, - Duration = duration, - From = VerticalOffset, - To = newOffset, - }; - - doubleAnimation.Completed += DoubleAnimation_Completed; - - _animationRunning = true; - BeginAnimation(ScrollViewerUtils.VerticalOffsetProperty, doubleAnimation, HandoffBehavior.SnapshotAndReplace); - } - - _lastVerticalScrollingDelta = e.Delta; - } - else if (horizontal) - { - if (ScrollInfo is IScrollInfo scrollInfo) - { - // 考虑到 VirtualizingPanel 可能是虚拟的大小, 所以这里需要校正 Delta - scrollDelta *= scrollInfo.ViewportWidth / (_scrollContentPresenter?.ActualWidth ?? ActualWidth); - } - - var sameDirectionAsLast = Math.Sign(e.Delta) == Math.Sign(_lastHorizontalScrollingDelta); - var nowOffset = sameDirectionAsLast && _animationRunning ? HorizontalOffsetTarget : HorizontalOffset; - var newOffset = nowOffset - scrollDelta; - - if (newOffset < 0) - newOffset = 0; - if (newOffset > ScrollableWidth) - newOffset = ScrollableWidth; - - SetValue(HorizontalOffsetTargetPropertyKey, newOffset); - BeginAnimation(ScrollViewerUtils.HorizontalOffsetProperty, null); - - if (!EnableScrollingAnimation || isTouchpadScrolling) - { - ScrollToHorizontalOffset(newOffset); - } - else - { - var diff = newOffset - HorizontalOffset; - var absDiff = Math.Abs(diff); - var duration = ScrollingAnimationDuration; - if (absDiff < Mouse.MouseWheelDeltaForOneLine) - { - duration = new Duration(TimeSpan.FromTicks((long)(duration.TimeSpan.Ticks * absDiff / Mouse.MouseWheelDeltaForOneLine))); - } - - DoubleAnimation doubleAnimation = new DoubleAnimation() - { - EasingFunction = _scrollingAnimationEase, - Duration = duration, - From = HorizontalOffset, - To = newOffset, - }; - - doubleAnimation.Completed += DoubleAnimation_Completed; - - _animationRunning = true; - BeginAnimation(ScrollViewerUtils.HorizontalOffsetProperty, doubleAnimation, HandoffBehavior.SnapshotAndReplace); - } - - _lastHorizontalScrollingDelta = e.Delta; - } - - _lastScrollingTick = tickCount; - _lastScrollDelta = e.Delta; - - e.Handled = true; - } - - private void DoubleAnimation_Completed(object? sender, EventArgs e) - { - _animationRunning = false; - } - - /// - protected override void OnMouseWheel(MouseWheelEventArgs e) - { - if (!ScrollWithWheelDelta) - { - base.OnMouseWheel(e); - } - else - { - Debug.WriteLine(e.Delta); - - CoreScrollWithWheelDelta(e); - } - } - - /// - /// The horizontal offset of scrolling target - /// - public double HorizontalOffsetTarget - { - get { return (double)GetValue(HorizontalOffsetTargetProperty); } - } - - /// - /// The vertical offset of scrolling target - /// - public double VerticalOffsetTarget - { - get { return (double)GetValue(VerticalOffsetTargetProperty); } - } - - /// - /// Scroll with wheel delta instead of scrolling fixed number of lines - /// - public bool ScrollWithWheelDelta - { - get { return (bool)GetValue(ScrollWithWheelDeltaProperty); } - set { SetValue(ScrollWithWheelDeltaProperty, value); } - } - - /// - /// Enable scrolling animation while using mouse
- /// You need to set ScrollWithWheelDelta to true to use this - ///
- public bool EnableScrollingAnimation - { - get { return (bool)GetValue(EnableScrollingAnimationProperty); } - set { SetValue(EnableScrollingAnimationProperty, value); } - } - - /// - /// Scrolling animation duration - /// - public Duration ScrollingAnimationDuration - { - get { return (Duration)GetValue(ScrollingAnimationDurationProperty); } - set { SetValue(ScrollingAnimationDurationProperty, value); } - } - - /// - /// Delta value factor while mouse scrolling - /// - public double MouseScrollDeltaFactor - { - get { return (double)GetValue(MouseScrollDeltaFactorProperty); } - set { SetValue(MouseScrollDeltaFactorProperty, value); } - } - - /// - /// Delta value factor while touchpad scrolling - /// - public double TouchpadScrollDeltaFactor - { - get { return (double)GetValue(TouchpadScrollDeltaFactorProperty); } - set { SetValue(TouchpadScrollDeltaFactorProperty, value); } - } - - /// - /// Always handle mouse wheel scrolling.
- /// (Especially in "TextBox") - ///
- public bool AlwaysHandleMouseWheelScrolling - { - get { return (bool)GetValue(AlwaysHandleMouseWheelScrollingProperty); } - set { SetValue(AlwaysHandleMouseWheelScrollingProperty, value); } - } - - - - - - - - - /// - /// The key needed set a read-only property - /// - public static readonly DependencyPropertyKey HorizontalOffsetTargetPropertyKey = - DependencyProperty.RegisterReadOnly(nameof(HorizontalOffsetTarget), typeof(double), typeof(ScrollViewer), new PropertyMetadata(0.0)); - - /// - /// The key needed set a read-only property - /// - public static readonly DependencyPropertyKey VerticalOffsetTargetPropertyKey = - DependencyProperty.RegisterReadOnly(nameof(VerticalOffsetTarget), typeof(double), typeof(ScrollViewer), new PropertyMetadata(0.0)); - - /// - /// The key needed set a read-only property - /// - public static readonly DependencyProperty HorizontalOffsetTargetProperty = - HorizontalOffsetTargetPropertyKey.DependencyProperty; - - /// - /// The key needed set a read-only property - /// - public static readonly DependencyProperty VerticalOffsetTargetProperty = - VerticalOffsetTargetPropertyKey.DependencyProperty; - - - - /// - /// Get value of ScrollWithWheelDelta property - /// - /// - /// - public static bool GetScrollWithWheelDelta(DependencyObject obj) - { - return (bool)obj.GetValue(ScrollWithWheelDeltaProperty); - } - - /// - /// Set value of ScrollWithWheelDelta property - /// - /// - /// - public static void SetScrollWithWheelDelta(DependencyObject obj, bool value) - { - obj.SetValue(ScrollWithWheelDeltaProperty, value); - } - - /// - /// Get value of EnableScrollingAnimation property - /// - /// - /// - public static bool GetEnableScrollingAnimation(DependencyObject obj) - { - return (bool)obj.GetValue(EnableScrollingAnimationProperty); - } - - /// - /// Set value of EnableScrollingAnimation property - /// - /// - /// - public static void SetEnableScrollingAnimation(DependencyObject obj, bool value) - { - obj.SetValue(EnableScrollingAnimationProperty, value); - } - - /// - /// Get value of ScrollingAnimationDuration property - /// - /// - /// - public static Duration GetScrollingAnimationDuration(DependencyObject obj) - { - return (Duration)obj.GetValue(ScrollingAnimationDurationProperty); - } - - /// - /// Set value of ScrollingAnimationDuration property - /// - /// - /// - public static void SetScrollingAnimationDuration(DependencyObject obj, Duration value) - { - obj.SetValue(ScrollingAnimationDurationProperty, value); - } - - - /// - /// Set value of AlwaysHandleMouseWheelScrolling property - /// - /// - /// - public static bool GetAlwaysHandleMouseWheelScrolling(DependencyObject obj) - { - return (bool)obj.GetValue(AlwaysHandleMouseWheelScrollingProperty); - } - - /// - /// Get value of AlwaysHandleMouseWheelScrolling property - /// - /// - /// - public static void SetAlwaysHandleMouseWheelScrolling(DependencyObject obj, bool value) - { - obj.SetValue(AlwaysHandleMouseWheelScrollingProperty, value); - } - - - /// - /// The DependencyProperty of property. - /// - public static readonly DependencyProperty ScrollWithWheelDeltaProperty = - DependencyProperty.RegisterAttached(nameof(ScrollWithWheelDelta), typeof(bool), typeof(ScrollViewer), - new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits)); - - /// - /// The DependencyProperty of property. - /// - public static readonly DependencyProperty EnableScrollingAnimationProperty = - DependencyProperty.RegisterAttached(nameof(EnableScrollingAnimation), typeof(bool), typeof(ScrollViewer), - new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits)); - - /// - /// The DependencyProperty of property. - /// - public static readonly DependencyProperty ScrollingAnimationDurationProperty = - DependencyProperty.RegisterAttached(nameof(ScrollingAnimationDuration), typeof(Duration), typeof(ScrollViewer), - new FrameworkPropertyMetadata(new Duration(TimeSpan.FromMilliseconds(250)), FrameworkPropertyMetadataOptions.Inherits), ValidateScrollingAnimationDuration); - - /// - /// The DependencyProperty of property - /// - public static readonly DependencyProperty AlwaysHandleMouseWheelScrollingProperty = - DependencyProperty.RegisterAttached(nameof(AlwaysHandleMouseWheelScrolling), typeof(bool), typeof(ScrollViewer), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits)); - - /// - /// The DependencyProperty of property - /// - public static readonly DependencyProperty MouseScrollDeltaFactorProperty = - DependencyProperty.Register(nameof(MouseScrollDeltaFactor), typeof(double), typeof(ScrollViewer), new PropertyMetadata(1.0)); - - /// - /// The DependencyProperty of property - /// - public static readonly DependencyProperty TouchpadScrollDeltaFactorProperty = - DependencyProperty.Register(nameof(TouchpadScrollDeltaFactor), typeof(double), typeof(ScrollViewer), new PropertyMetadata(1.0)); - - private static bool ValidateScrollingAnimationDuration(object value) - => value is Duration duration && duration.HasTimeSpan; - } + } + + private delegate bool GetBool(ScrollViewer scrollViewer); + private static readonly GetBool _propertyHandlesMouseWheelScrollingGetter; + private static readonly IEasingFunction _scrollingAnimationEase = new CubicEase() { EasingMode = EasingMode.EaseOut }; + private const long _millisecondsBetweenTouchpadScrolling = 100; + + private bool _animationRunning = false; + private int _lastScrollDelta = 0; + private int _lastVerticalScrollingDelta = 0; + private int _lastHorizontalScrollingDelta = 0; + private long _lastScrollingTick; + + private FrameworkElement? _scrollContentPresenter; + + /// + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + _scrollContentPresenter = GetTemplateChild("PART_ScrollContentPresenter") as FrameworkElement; + } + + private void CoreScrollWithWheelDelta(MouseWheelEventArgs e) + { + if (e.Handled) + { + return; + } + + if (!AlwaysHandleMouseWheelScrolling && + !_propertyHandlesMouseWheelScrollingGetter.Invoke(this)) + { + return; + } + + bool vertical = ExtentHeight > 0; + bool horizontal = ExtentWidth > 0; + + var tickCount = Environment.TickCount; + var isTouchpadScrolling = + e.Delta % Mouse.MouseWheelDeltaForOneLine != 0 || + (tickCount - _lastScrollingTick < _millisecondsBetweenTouchpadScrolling && _lastScrollDelta % Mouse.MouseWheelDeltaForOneLine != 0); + + double scrollDelta = e.Delta; + + if (isTouchpadScrolling) + { + // touchpad 应该滚动更慢一些, 所以这里预先除以一个合适的值 + scrollDelta /= 2; + + // + scrollDelta *= TouchpadScrollDeltaFactor; + } + else + { + scrollDelta *= MouseScrollDeltaFactor; + } + + if (vertical) + { + if (ScrollInfo is IScrollInfo scrollInfo) + { + // 考虑到 VirtualizingPanel 可能是虚拟的大小, 所以这里需要校正 Delta + scrollDelta *= scrollInfo.ViewportHeight / (_scrollContentPresenter?.ActualHeight ?? ActualHeight); + } + + var sameDirectionAsLast = Math.Sign(e.Delta) == Math.Sign(_lastVerticalScrollingDelta); + var nowOffset = sameDirectionAsLast && _animationRunning ? VerticalOffsetTarget : VerticalOffset; + var newOffset = nowOffset - scrollDelta; + + if (newOffset < 0) + newOffset = 0; + if (newOffset > ScrollableHeight) + newOffset = ScrollableHeight; + + SetValue(VerticalOffsetTargetPropertyKey, newOffset); + BeginAnimation(ScrollViewerUtils.VerticalOffsetProperty, null); + + if (!EnableScrollingAnimation || isTouchpadScrolling) + { + ScrollToVerticalOffset(newOffset); + } + else + { + var diff = newOffset - VerticalOffset; + var absDiff = Math.Abs(diff); + var duration = ScrollingAnimationDuration; + if (absDiff < Mouse.MouseWheelDeltaForOneLine) + { + duration = new Duration(TimeSpan.FromTicks((long)(duration.TimeSpan.Ticks * absDiff / Mouse.MouseWheelDeltaForOneLine))); + } + + DoubleAnimation doubleAnimation = new DoubleAnimation() { + EasingFunction = _scrollingAnimationEase, + Duration = duration, + From = VerticalOffset, + To = newOffset, + }; + + doubleAnimation.Completed += DoubleAnimation_Completed; + + _animationRunning = true; + BeginAnimation(ScrollViewerUtils.VerticalOffsetProperty, doubleAnimation, HandoffBehavior.SnapshotAndReplace); + } + + _lastVerticalScrollingDelta = e.Delta; + } + else if (horizontal) + { + if (ScrollInfo is IScrollInfo scrollInfo) + { + // 考虑到 VirtualizingPanel 可能是虚拟的大小, 所以这里需要校正 Delta + scrollDelta *= scrollInfo.ViewportWidth / (_scrollContentPresenter?.ActualWidth ?? ActualWidth); + } + + var sameDirectionAsLast = Math.Sign(e.Delta) == Math.Sign(_lastHorizontalScrollingDelta); + var nowOffset = sameDirectionAsLast && _animationRunning ? HorizontalOffsetTarget : HorizontalOffset; + var newOffset = nowOffset - scrollDelta; + + if (newOffset < 0) + newOffset = 0; + if (newOffset > ScrollableWidth) + newOffset = ScrollableWidth; + + SetValue(HorizontalOffsetTargetPropertyKey, newOffset); + BeginAnimation(ScrollViewerUtils.HorizontalOffsetProperty, null); + + if (!EnableScrollingAnimation || isTouchpadScrolling) + { + ScrollToHorizontalOffset(newOffset); + } + else + { + var diff = newOffset - HorizontalOffset; + var absDiff = Math.Abs(diff); + var duration = ScrollingAnimationDuration; + if (absDiff < Mouse.MouseWheelDeltaForOneLine) + { + duration = new Duration(TimeSpan.FromTicks((long)(duration.TimeSpan.Ticks * absDiff / Mouse.MouseWheelDeltaForOneLine))); + } + + DoubleAnimation doubleAnimation = new DoubleAnimation() { + EasingFunction = _scrollingAnimationEase, + Duration = duration, + From = HorizontalOffset, + To = newOffset, + }; + + doubleAnimation.Completed += DoubleAnimation_Completed; + + _animationRunning = true; + BeginAnimation(ScrollViewerUtils.HorizontalOffsetProperty, doubleAnimation, HandoffBehavior.SnapshotAndReplace); + } + + _lastHorizontalScrollingDelta = e.Delta; + } + + _lastScrollingTick = tickCount; + _lastScrollDelta = e.Delta; + + e.Handled = true; + } + + private void DoubleAnimation_Completed(object? sender, EventArgs e) + { + _animationRunning = false; + } + + /// + protected override void OnMouseWheel(MouseWheelEventArgs e) + { + if (!ScrollWithWheelDelta) + { + base.OnMouseWheel(e); + } + else + { + Debug.WriteLine(e.Delta); + + CoreScrollWithWheelDelta(e); + } + } + + /// + /// The horizontal offset of scrolling target + /// + public double HorizontalOffsetTarget { + get { return (double)GetValue(HorizontalOffsetTargetProperty); } + } + + /// + /// The vertical offset of scrolling target + /// + public double VerticalOffsetTarget { + get { return (double)GetValue(VerticalOffsetTargetProperty); } + } + + /// + /// Scroll with wheel delta instead of scrolling fixed number of lines + /// + public bool ScrollWithWheelDelta { + get { return (bool)GetValue(ScrollWithWheelDeltaProperty); } + set { SetValue(ScrollWithWheelDeltaProperty, value); } + } + + /// + /// Enable scrolling animation while using mouse
+ /// You need to set ScrollWithWheelDelta to true to use this + ///
+ public bool EnableScrollingAnimation { + get { return (bool)GetValue(EnableScrollingAnimationProperty); } + set { SetValue(EnableScrollingAnimationProperty, value); } + } + + /// + /// Scrolling animation duration + /// + public Duration ScrollingAnimationDuration { + get { return (Duration)GetValue(ScrollingAnimationDurationProperty); } + set { SetValue(ScrollingAnimationDurationProperty, value); } + } + + /// + /// Delta value factor while mouse scrolling + /// + public double MouseScrollDeltaFactor { + get { return (double)GetValue(MouseScrollDeltaFactorProperty); } + set { SetValue(MouseScrollDeltaFactorProperty, value); } + } + + /// + /// Delta value factor while touchpad scrolling + /// + public double TouchpadScrollDeltaFactor { + get { return (double)GetValue(TouchpadScrollDeltaFactorProperty); } + set { SetValue(TouchpadScrollDeltaFactorProperty, value); } + } + + /// + /// Always handle mouse wheel scrolling.
+ /// (Especially in "TextBox") + ///
+ public bool AlwaysHandleMouseWheelScrolling { + get { return (bool)GetValue(AlwaysHandleMouseWheelScrollingProperty); } + set { SetValue(AlwaysHandleMouseWheelScrollingProperty, value); } + } + + + + + + + + + /// + /// The key needed set a read-only property + /// + public static readonly DependencyPropertyKey HorizontalOffsetTargetPropertyKey = + DependencyProperty.RegisterReadOnly(nameof(HorizontalOffsetTarget), typeof(double), typeof(ScrollViewer), new PropertyMetadata(0.0)); + + /// + /// The key needed set a read-only property + /// + public static readonly DependencyPropertyKey VerticalOffsetTargetPropertyKey = + DependencyProperty.RegisterReadOnly(nameof(VerticalOffsetTarget), typeof(double), typeof(ScrollViewer), new PropertyMetadata(0.0)); + + /// + /// The key needed set a read-only property + /// + public static readonly DependencyProperty HorizontalOffsetTargetProperty = + HorizontalOffsetTargetPropertyKey.DependencyProperty; + + /// + /// The key needed set a read-only property + /// + public static readonly DependencyProperty VerticalOffsetTargetProperty = + VerticalOffsetTargetPropertyKey.DependencyProperty; + + + + /// + /// Get value of ScrollWithWheelDelta property + /// + /// + /// + public static bool GetScrollWithWheelDelta(DependencyObject obj) + { + return (bool)obj.GetValue(ScrollWithWheelDeltaProperty); + } + + /// + /// Set value of ScrollWithWheelDelta property + /// + /// + /// + public static void SetScrollWithWheelDelta(DependencyObject obj, bool value) + { + obj.SetValue(ScrollWithWheelDeltaProperty, value); + } + + /// + /// Get value of EnableScrollingAnimation property + /// + /// + /// + public static bool GetEnableScrollingAnimation(DependencyObject obj) + { + return (bool)obj.GetValue(EnableScrollingAnimationProperty); + } + + /// + /// Set value of EnableScrollingAnimation property + /// + /// + /// + public static void SetEnableScrollingAnimation(DependencyObject obj, bool value) + { + obj.SetValue(EnableScrollingAnimationProperty, value); + } + + /// + /// Get value of ScrollingAnimationDuration property + /// + /// + /// + public static Duration GetScrollingAnimationDuration(DependencyObject obj) + { + return (Duration)obj.GetValue(ScrollingAnimationDurationProperty); + } + + /// + /// Set value of ScrollingAnimationDuration property + /// + /// + /// + public static void SetScrollingAnimationDuration(DependencyObject obj, Duration value) + { + obj.SetValue(ScrollingAnimationDurationProperty, value); + } + + + /// + /// Set value of AlwaysHandleMouseWheelScrolling property + /// + /// + /// + public static bool GetAlwaysHandleMouseWheelScrolling(DependencyObject obj) + { + return (bool)obj.GetValue(AlwaysHandleMouseWheelScrollingProperty); + } + + /// + /// Get value of AlwaysHandleMouseWheelScrolling property + /// + /// + /// + public static void SetAlwaysHandleMouseWheelScrolling(DependencyObject obj, bool value) + { + obj.SetValue(AlwaysHandleMouseWheelScrollingProperty, value); + } + + + /// + /// The DependencyProperty of property. + /// + public static readonly DependencyProperty ScrollWithWheelDeltaProperty = + DependencyProperty.RegisterAttached(nameof(ScrollWithWheelDelta), typeof(bool), typeof(ScrollViewer), + new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits)); + + /// + /// The DependencyProperty of property. + /// + public static readonly DependencyProperty EnableScrollingAnimationProperty = + DependencyProperty.RegisterAttached(nameof(EnableScrollingAnimation), typeof(bool), typeof(ScrollViewer), + new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits)); + + /// + /// The DependencyProperty of property. + /// + public static readonly DependencyProperty ScrollingAnimationDurationProperty = + DependencyProperty.RegisterAttached(nameof(ScrollingAnimationDuration), typeof(Duration), typeof(ScrollViewer), + new FrameworkPropertyMetadata(new Duration(TimeSpan.FromMilliseconds(250)), FrameworkPropertyMetadataOptions.Inherits), ValidateScrollingAnimationDuration); + + /// + /// The DependencyProperty of property + /// + public static readonly DependencyProperty AlwaysHandleMouseWheelScrollingProperty = + DependencyProperty.RegisterAttached(nameof(AlwaysHandleMouseWheelScrolling), typeof(bool), typeof(ScrollViewer), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits)); + + /// + /// The DependencyProperty of property + /// + public static readonly DependencyProperty MouseScrollDeltaFactorProperty = + DependencyProperty.Register(nameof(MouseScrollDeltaFactor), typeof(double), typeof(ScrollViewer), new PropertyMetadata(1.0)); + + /// + /// The DependencyProperty of property + /// + public static readonly DependencyProperty TouchpadScrollDeltaFactorProperty = + DependencyProperty.Register(nameof(TouchpadScrollDeltaFactor), typeof(double), typeof(ScrollViewer), new PropertyMetadata(1.0)); + + private static bool ValidateScrollingAnimationDuration(object value) + => value is Duration duration && duration.HasTimeSpan; + } } diff --git a/EleCho.WpfSuite/MathHelper.cs b/EleCho.WpfSuite/MathHelper.cs index e82b1f018b..cb8ca4e301 100644 --- a/EleCho.WpfSuite/MathHelper.cs +++ b/EleCho.WpfSuite/MathHelper.cs @@ -8,68 +8,68 @@ namespace EleCho.WpfSuite { - internal static class MathHelper - { - internal const double DBL_EPSILON = 2.2204460492503131e-016; + internal static class MathHelper + { + internal const double DBL_EPSILON = 2.2204460492503131e-016; - public static bool AreClose(double value1, double value2) => - // ReSharper disable once CompareOfFloatsByEqualityOperator - value1 == value2 || IsVerySmall(value1 - value2); + public static bool AreClose(double value1, double value2) => + // ReSharper disable once CompareOfFloatsByEqualityOperator + value1 == value2 || IsVerySmall(value1 - value2); - public static double Lerp(double x, double y, double alpha) => x * (1.0 - alpha) + y * alpha; + public static double Lerp(double x, double y, double alpha) => x * (1.0 - alpha) + y * alpha; - public static bool IsVerySmall(double value) => Math.Abs(value) < 1E-06; + public static bool IsVerySmall(double value) => Math.Abs(value) < 1E-06; - public static bool IsZero(double value) => Math.Abs(value) < 10.0 * DBL_EPSILON; + public static bool IsZero(double value) => Math.Abs(value) < 10.0 * DBL_EPSILON; - public static bool IsFiniteDouble(double x) => !double.IsInfinity(x) && !double.IsNaN(x); + public static bool IsFiniteDouble(double x) => !double.IsInfinity(x) && !double.IsNaN(x); - public static double DoubleFromMantissaAndExponent(double x, int exp) => x * Math.Pow(2.0, exp); + public static double DoubleFromMantissaAndExponent(double x, int exp) => x * Math.Pow(2.0, exp); - public static bool GreaterThan(double value1, double value2) => value1 > value2 && !AreClose(value1, value2); + public static bool GreaterThan(double value1, double value2) => value1 > value2 && !AreClose(value1, value2); - public static bool GreaterThanOrClose(double value1, double value2) - { - if (value1 <= value2) - { - return AreClose(value1, value2); - } - return true; - } + public static bool GreaterThanOrClose(double value1, double value2) + { + if (value1 <= value2) + { + return AreClose(value1, value2); + } + return true; + } - public static double Hypotenuse(double x, double y) => Math.Sqrt(x * x + y * y); + public static double Hypotenuse(double x, double y) => Math.Sqrt(x * x + y * y); - public static bool LessThan(double value1, double value2) => value1 < value2 && !AreClose(value1, value2); + public static bool LessThan(double value1, double value2) => value1 < value2 && !AreClose(value1, value2); - public static bool LessThanOrClose(double value1, double value2) - { - if (value1 >= value2) - { - return AreClose(value1, value2); - } - return true; - } + public static bool LessThanOrClose(double value1, double value2) + { + if (value1 >= value2) + { + return AreClose(value1, value2); + } + return true; + } - public static double EnsureRange(double value, double? min, double? max) - { - if (min.HasValue && value < min.Value) - { - return min.Value; - } - if (max.HasValue && value > max.Value) - { - return max.Value; - } - return value; - } + public static double EnsureRange(double value, double? min, double? max) + { + if (min.HasValue && value < min.Value) + { + return min.Value; + } + if (max.HasValue && value > max.Value) + { + return max.Value; + } + return value; + } - public static double SafeDivide(double lhs, double rhs, double fallback) - { - if (!IsVerySmall(rhs)) - { - return lhs / rhs; - } - return fallback; - } - } + public static double SafeDivide(double lhs, double rhs, double fallback) + { + if (!IsVerySmall(rhs)) + { + return lhs / rhs; + } + return fallback; + } + } } diff --git a/EleCho.WpfSuite/Themes/Generic.xaml b/EleCho.WpfSuite/Themes/Generic.xaml index 6b82c08468..be8b8bb3a5 100644 --- a/EleCho.WpfSuite/Themes/Generic.xaml +++ b/EleCho.WpfSuite/Themes/Generic.xaml @@ -1,7 +1,7 @@ - - - - + + + + diff --git a/EleCho.WpfSuite/Utilities/ScrollViewerUtils.cs b/EleCho.WpfSuite/Utilities/ScrollViewerUtils.cs index d204febb6c..88f3f6023b 100644 --- a/EleCho.WpfSuite/Utilities/ScrollViewerUtils.cs +++ b/EleCho.WpfSuite/Utilities/ScrollViewerUtils.cs @@ -5,116 +5,116 @@ namespace EleCho.WpfSuite { - /// - /// ScrollViewer Utilities - /// - public static class ScrollViewerUtils - { - /// - /// Get value of VerticalOffset property - /// - /// - /// - public static double GetVerticalOffset(DependencyObject d) - { - if (d is ScrollViewer sv) - { - return sv.VerticalOffset; - } - else if (d is ScrollContentPresenter scp) - { - return scp.VerticalOffset; - } + /// + /// ScrollViewer Utilities + /// + public static class ScrollViewerUtils + { + /// + /// Get value of VerticalOffset property + /// + /// + /// + public static double GetVerticalOffset(DependencyObject d) + { + if (d is ScrollViewer sv) + { + return sv.VerticalOffset; + } + else if (d is ScrollContentPresenter scp) + { + return scp.VerticalOffset; + } - return (double)d.GetValue(VerticalOffsetProperty); - } + return (double)d.GetValue(VerticalOffsetProperty); + } - /// - /// Set value of VerticalOffset property - /// - /// - /// - public static void SetVerticalOffset(DependencyObject obj, double value) - { - obj.SetValue(VerticalOffsetProperty, value); - } + /// + /// Set value of VerticalOffset property + /// + /// + /// + public static void SetVerticalOffset(DependencyObject obj, double value) + { + obj.SetValue(VerticalOffsetProperty, value); + } - /// - /// Get value of HorizontalOffset property - /// - /// - /// - public static double GetHorizontalOffset(DependencyObject d) - { - if (d is ScrollViewer sv) - { - return sv.HorizontalOffset; - } - else if (d is ScrollContentPresenter scp) - { - return scp.HorizontalOffset; - } + /// + /// Get value of HorizontalOffset property + /// + /// + /// + public static double GetHorizontalOffset(DependencyObject d) + { + if (d is ScrollViewer sv) + { + return sv.HorizontalOffset; + } + else if (d is ScrollContentPresenter scp) + { + return scp.HorizontalOffset; + } - return (double)d.GetValue(HorizontalOffsetProperty); - } + return (double)d.GetValue(HorizontalOffsetProperty); + } - /// - /// Set value of HorizontalOffset property - /// - /// - /// - public static void SetHorizontalOffset(DependencyObject obj, double value) - { - obj.SetValue(HorizontalOffsetProperty, value); - } + /// + /// Set value of HorizontalOffset property + /// + /// + /// + public static void SetHorizontalOffset(DependencyObject obj, double value) + { + obj.SetValue(HorizontalOffsetProperty, value); + } - /// - /// The DependencyProperty of VerticalOffset property - /// - public static readonly DependencyProperty VerticalOffsetProperty = - DependencyProperty.RegisterAttached("VerticalOffset", typeof(double), typeof(ScrollViewerUtils), new PropertyMetadata(0.0, VerticalOffsetChangedCallback)); + /// + /// The DependencyProperty of VerticalOffset property + /// + public static readonly DependencyProperty VerticalOffsetProperty = + DependencyProperty.RegisterAttached("VerticalOffset", typeof(double), typeof(ScrollViewerUtils), new PropertyMetadata(0.0, VerticalOffsetChangedCallback)); - /// - /// The DependencyProperty of HorizontalOffset property - /// - public static readonly DependencyProperty HorizontalOffsetProperty = - DependencyProperty.RegisterAttached("HorizontalOffset", typeof(double), typeof(ScrollViewerUtils), new PropertyMetadata(0.0, HorizontalOffsetChangedCallback)); + /// + /// The DependencyProperty of HorizontalOffset property + /// + public static readonly DependencyProperty HorizontalOffsetProperty = + DependencyProperty.RegisterAttached("HorizontalOffset", typeof(double), typeof(ScrollViewerUtils), new PropertyMetadata(0.0, HorizontalOffsetChangedCallback)); - private static void VerticalOffsetChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - if (e.NewValue is not double offset) - { - return; - } + private static void VerticalOffsetChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (e.NewValue is not double offset) + { + return; + } - if (d is ScrollViewer sv) - { - sv.ScrollToVerticalOffset(offset); - } - else if (d is ScrollContentPresenter scp) - { - scp.SetVerticalOffset(offset); - } - } + if (d is ScrollViewer sv) + { + sv.ScrollToVerticalOffset(offset); + } + else if (d is ScrollContentPresenter scp) + { + scp.SetVerticalOffset(offset); + } + } - private static void HorizontalOffsetChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - if (e.NewValue is not double offset) - { - return; - } + private static void HorizontalOffsetChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (e.NewValue is not double offset) + { + return; + } - if (d is ScrollViewer sv) - { - sv.ScrollToHorizontalOffset(offset); - } - else if (d is ScrollContentPresenter scp) - { - scp.SetHorizontalOffset(offset); - } - } - } + if (d is ScrollViewer sv) + { + sv.ScrollToHorizontalOffset(offset); + } + else if (d is ScrollContentPresenter scp) + { + scp.SetHorizontalOffset(offset); + } + } + } } diff --git a/EleCho.WpfSuite/ValueConverters/FallbackConverter.cs b/EleCho.WpfSuite/ValueConverters/FallbackConverter.cs index 6741b74616..89aaf17e78 100644 --- a/EleCho.WpfSuite/ValueConverters/FallbackConverter.cs +++ b/EleCho.WpfSuite/ValueConverters/FallbackConverter.cs @@ -4,23 +4,23 @@ namespace EleCho.WpfSuite { - /// - /// Fallback between multiple values, return the first non-null value - /// - public class FallbackConverter : SingletonMultiValueConverterBase - { - /// - public override object? Convert(object?[] values, Type targetType, object? parameter, CultureInfo culture) - { - foreach (var value in values) - { - if (value is not null && - value != DependencyProperty.UnsetValue) - return value; - } + /// + /// Fallback between multiple values, return the first non-null value + /// + public class FallbackConverter : SingletonMultiValueConverterBase + { + /// + public override object? Convert(object?[] values, Type targetType, object? parameter, CultureInfo culture) + { + foreach (var value in values) + { + if (value is not null && + value != DependencyProperty.UnsetValue) + return value; + } - return null; - } - } + return null; + } + } } diff --git a/EleCho.WpfSuite/ValueConverters/MultiValueConverterBase.cs b/EleCho.WpfSuite/ValueConverters/MultiValueConverterBase.cs index 72a9ebe049..63489213ad 100644 --- a/EleCho.WpfSuite/ValueConverters/MultiValueConverterBase.cs +++ b/EleCho.WpfSuite/ValueConverters/MultiValueConverterBase.cs @@ -4,19 +4,19 @@ namespace EleCho.WpfSuite { - /// - /// Base class of multi value converter - /// - /// - public abstract class MultiValueConverterBase : IMultiValueConverter - { - /// - public abstract object? Convert(object?[] values, Type targetType, object? parameter, CultureInfo culture); + /// + /// Base class of multi value converter + /// + /// + public abstract class MultiValueConverterBase : IMultiValueConverter + { + /// + public abstract object? Convert(object?[] values, Type targetType, object? parameter, CultureInfo culture); - /// - public virtual object?[] ConvertBack(object? value, Type[] targetTypes, object? parameter, CultureInfo culture) - { - throw new NotSupportedException(); - } - } + /// + public virtual object?[] ConvertBack(object? value, Type[] targetTypes, object? parameter, CultureInfo culture) + { + throw new NotSupportedException(); + } + } } diff --git a/EleCho.WpfSuite/ValueConverters/SingletonMultiValueConverterBase.cs b/EleCho.WpfSuite/ValueConverters/SingletonMultiValueConverterBase.cs index 538ea2f15d..b436fcbebb 100644 --- a/EleCho.WpfSuite/ValueConverters/SingletonMultiValueConverterBase.cs +++ b/EleCho.WpfSuite/ValueConverters/SingletonMultiValueConverterBase.cs @@ -1,17 +1,17 @@ namespace EleCho.WpfSuite { - /// - /// Base class of singleton multi value converter - /// - /// - public abstract class SingletonMultiValueConverterBase : MultiValueConverterBase - where TSelf : SingletonMultiValueConverterBase, new() - { - private static TSelf? _instance = null; + /// + /// Base class of singleton multi value converter + /// + /// + public abstract class SingletonMultiValueConverterBase : MultiValueConverterBase + where TSelf : SingletonMultiValueConverterBase, new() + { + private static TSelf? _instance = null; - /// - /// Get an instance of - /// - public static TSelf Instance => _instance ?? new(); - } + /// + /// Get an instance of + /// + public static TSelf Instance => _instance ?? new(); + } } From 050bb96c805e0641fb22fd7d067fd9a4eaba42de Mon Sep 17 00:00:00 2001 From: SlimeNull Date: Tue, 23 Jul 2024 08:42:39 +0800 Subject: [PATCH 5/7] Replacing inheritance-based smooth scrolling with Behavior implementation --- Directory.Packages.props | 3 +- EleCho.WpfSuite/AssemblyInfo.cs | 6 - EleCho.WpfSuite/Controls/ListBox.cs | 69 -------- .../Controls/ListBoxResources.xaml | 68 ------- EleCho.WpfSuite/Controls/ListView.cs | 60 ------- .../Controls/ListViewResources.xaml | 68 ------- EleCho.WpfSuite/EleCho.WpfSuite.csproj | 71 -------- EleCho.WpfSuite/MathHelper.cs | 75 -------- EleCho.WpfSuite/Themes/Generic.xaml | 7 - .../ValueConverters/FallbackConverter.cs | 26 --- .../MultiValueConverterBase.cs | 22 --- .../SingletonMultiValueConverterBase.cs | 17 -- ILSpy.sln | 10 +- ILSpy/Controls/ZoomScrollViewer.cs | 7 +- ILSpy/ILSpy.csproj | 2 +- ILSpy/MainWindow.xaml | 5 + ILSpy/Options/DecompilerSettingsPanel.xaml | 18 +- ILSpy/Options/DisplaySettingsPanel.xaml | 10 +- ILSpy/Search/SearchPane.xaml | 7 +- ILSpy/TextView/DecompilerTextView.xaml | 10 +- .../LibScrollingOptimization.csproj | 14 ++ .../ScrollViewerUtils.cs | 2 +- .../SmoothScrollingBehavior.cs | 166 ++++++++++-------- SharpTreeView/ICSharpCode.TreeView.csproj | 4 - SharpTreeView/SharpTreeView.cs | 2 +- SharpTreeView/Themes/Generic.xaml | 8 +- 26 files changed, 161 insertions(+), 596 deletions(-) delete mode 100644 EleCho.WpfSuite/AssemblyInfo.cs delete mode 100644 EleCho.WpfSuite/Controls/ListBox.cs delete mode 100644 EleCho.WpfSuite/Controls/ListBoxResources.xaml delete mode 100644 EleCho.WpfSuite/Controls/ListView.cs delete mode 100644 EleCho.WpfSuite/Controls/ListViewResources.xaml delete mode 100644 EleCho.WpfSuite/EleCho.WpfSuite.csproj delete mode 100644 EleCho.WpfSuite/MathHelper.cs delete mode 100644 EleCho.WpfSuite/Themes/Generic.xaml delete mode 100644 EleCho.WpfSuite/ValueConverters/FallbackConverter.cs delete mode 100644 EleCho.WpfSuite/ValueConverters/MultiValueConverterBase.cs delete mode 100644 EleCho.WpfSuite/ValueConverters/SingletonMultiValueConverterBase.cs create mode 100644 LibScrollingOptimization/LibScrollingOptimization.csproj rename {EleCho.WpfSuite/Utilities => LibScrollingOptimization}/ScrollViewerUtils.cs (98%) rename EleCho.WpfSuite/Controls/ScrollViewer.cs => LibScrollingOptimization/SmoothScrollingBehavior.cs (77%) diff --git a/Directory.Packages.props b/Directory.Packages.props index a8af6e158e..7647ddba41 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -30,7 +30,7 @@ - + @@ -46,6 +46,7 @@ +
diff --git a/EleCho.WpfSuite/AssemblyInfo.cs b/EleCho.WpfSuite/AssemblyInfo.cs deleted file mode 100644 index f0595295bf..0000000000 --- a/EleCho.WpfSuite/AssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -using System.Runtime.CompilerServices; -using System.Windows.Markup; - -[assembly: System.Windows.ThemeInfo(System.Windows.ResourceDictionaryLocation.None, System.Windows.ResourceDictionaryLocation.SourceAssembly)] -[assembly: XmlnsDefinition("https://schemas.elecho.dev/wpfsuite", "EleCho.WpfSuite")] -//[assembly: XmlnsDefinition("https://schemas.elecho.dev/wpfsuite", "EleCho.WpfSuite.Markup")] \ No newline at end of file diff --git a/EleCho.WpfSuite/Controls/ListBox.cs b/EleCho.WpfSuite/Controls/ListBox.cs deleted file mode 100644 index 633d01a12b..0000000000 --- a/EleCho.WpfSuite/Controls/ListBox.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; - -namespace EleCho.WpfSuite -{ - /// - public class ListBox : System.Windows.Controls.ListBox - { - static ListBox() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(ListBox), new FrameworkPropertyMetadata(typeof(ListBox))); - } - - /// - /// The CornerRadius property allows users to control the roundness of the corners independently by - /// setting a radius value for each corner. Radius values that are too large are scaled so that they - /// smoothly blend from corner to corner. - /// - public CornerRadius CornerRadius { - get { return (CornerRadius)GetValue(CornerRadiusProperty); } - set { SetValue(CornerRadiusProperty, value); } - } - - /// - /// Background when disabled - /// - public Brush DisabledBackground { - get { return (Brush)GetValue(DisabledBackgroundProperty); } - set { SetValue(DisabledBackgroundProperty, value); } - } - - /// - /// BorderBrush when pressed by mouse - /// - public Brush DisabledBorderBrush { - get { return (Brush)GetValue(DisabledBorderBrushProperty); } - set { SetValue(DisabledBorderBrushProperty, value); } - } - - /// - /// DependencyProperty of property - /// - public static readonly DependencyProperty CornerRadiusProperty = - System.Windows.Controls.Border.CornerRadiusProperty.AddOwner(typeof(ListBox)); - - /// - /// The DependencyProperty of property - /// - public static readonly DependencyProperty DisabledBackgroundProperty = - DependencyProperty.Register(nameof(DisabledBackground), typeof(Brush), typeof(ListBox), new FrameworkPropertyMetadata(null)); - - /// - /// The DependencyProperty of property - /// - public static readonly DependencyProperty DisabledBorderBrushProperty = - DependencyProperty.Register(nameof(DisabledBorderBrush), typeof(Brush), typeof(ListBox), new FrameworkPropertyMetadata(null)); - } -} diff --git a/EleCho.WpfSuite/Controls/ListBoxResources.xaml b/EleCho.WpfSuite/Controls/ListBoxResources.xaml deleted file mode 100644 index 980580efbe..0000000000 --- a/EleCho.WpfSuite/Controls/ListBoxResources.xaml +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/EleCho.WpfSuite/Controls/ListView.cs b/EleCho.WpfSuite/Controls/ListView.cs deleted file mode 100644 index cb9756d2d9..0000000000 --- a/EleCho.WpfSuite/Controls/ListView.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System.Windows; -using System.Windows.Media; - -namespace EleCho.WpfSuite -{ - /// - public class ListView : System.Windows.Controls.ListView - { - static ListView() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(ListView), new FrameworkPropertyMetadata(typeof(ListView))); - } - - - /// - /// The CornerRadius property allows users to control the roundness of the corners independently by - /// setting a radius value for each corner. Radius values that are too large are scaled so that they - /// smoothly blend from corner to corner. - /// - public CornerRadius CornerRadius { - get { return (CornerRadius)GetValue(CornerRadiusProperty); } - set { SetValue(CornerRadiusProperty, value); } - } - - /// - /// Background when disabled - /// - public Brush DisabledBackground { - get { return (Brush)GetValue(DisabledBackgroundProperty); } - set { SetValue(DisabledBackgroundProperty, value); } - } - - /// - /// BorderBrush when pressed by mouse - /// - public Brush DisabledBorderBrush { - get { return (Brush)GetValue(DisabledBorderBrushProperty); } - set { SetValue(DisabledBorderBrushProperty, value); } - } - - - /// - /// DependencyProperty of property - /// - public static readonly DependencyProperty CornerRadiusProperty = - System.Windows.Controls.Border.CornerRadiusProperty.AddOwner(typeof(ListView)); - - /// - /// The DependencyProperty of property - /// - public static readonly DependencyProperty DisabledBackgroundProperty = - DependencyProperty.Register(nameof(DisabledBackground), typeof(Brush), typeof(ListView), new FrameworkPropertyMetadata(null)); - - /// - /// The DependencyProperty of property - /// - public static readonly DependencyProperty DisabledBorderBrushProperty = - DependencyProperty.Register(nameof(DisabledBorderBrush), typeof(Brush), typeof(ListView), new FrameworkPropertyMetadata(null)); - } -} diff --git a/EleCho.WpfSuite/Controls/ListViewResources.xaml b/EleCho.WpfSuite/Controls/ListViewResources.xaml deleted file mode 100644 index b55d9454b3..0000000000 --- a/EleCho.WpfSuite/Controls/ListViewResources.xaml +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/EleCho.WpfSuite/EleCho.WpfSuite.csproj b/EleCho.WpfSuite/EleCho.WpfSuite.csproj deleted file mode 100644 index 1278187f88..0000000000 --- a/EleCho.WpfSuite/EleCho.WpfSuite.csproj +++ /dev/null @@ -1,71 +0,0 @@ - - - - net8.0-windows;net6.0-windows;net48;net47;net46;net45 - enable - latest - true - true - EleCho.WpfSuite - true - true - - 0.6.0 - - EleCho - Copyright © 2024 EleCho - https://wpfsuite.elecho.dev - logo.png - WPF;MVVM;XAML;Toolkit;Control;Layout;Transition;Converter;Animation;MarkupExtension;BindingProxy - WPF layout panels, controls, value converters, markup extensions, transitions and utilities - MIT - README.md - https://github.com/OrgEleCho/EleCho.WpfSuite - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MSBuild:Compile - - - - - - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - - - - diff --git a/EleCho.WpfSuite/MathHelper.cs b/EleCho.WpfSuite/MathHelper.cs deleted file mode 100644 index cb8ca4e301..0000000000 --- a/EleCho.WpfSuite/MathHelper.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Controls; -using System.Windows; - -namespace EleCho.WpfSuite -{ - internal static class MathHelper - { - internal const double DBL_EPSILON = 2.2204460492503131e-016; - - public static bool AreClose(double value1, double value2) => - // ReSharper disable once CompareOfFloatsByEqualityOperator - value1 == value2 || IsVerySmall(value1 - value2); - - public static double Lerp(double x, double y, double alpha) => x * (1.0 - alpha) + y * alpha; - - public static bool IsVerySmall(double value) => Math.Abs(value) < 1E-06; - - public static bool IsZero(double value) => Math.Abs(value) < 10.0 * DBL_EPSILON; - - public static bool IsFiniteDouble(double x) => !double.IsInfinity(x) && !double.IsNaN(x); - - public static double DoubleFromMantissaAndExponent(double x, int exp) => x * Math.Pow(2.0, exp); - - public static bool GreaterThan(double value1, double value2) => value1 > value2 && !AreClose(value1, value2); - - public static bool GreaterThanOrClose(double value1, double value2) - { - if (value1 <= value2) - { - return AreClose(value1, value2); - } - return true; - } - - public static double Hypotenuse(double x, double y) => Math.Sqrt(x * x + y * y); - - public static bool LessThan(double value1, double value2) => value1 < value2 && !AreClose(value1, value2); - - public static bool LessThanOrClose(double value1, double value2) - { - if (value1 >= value2) - { - return AreClose(value1, value2); - } - return true; - } - - public static double EnsureRange(double value, double? min, double? max) - { - if (min.HasValue && value < min.Value) - { - return min.Value; - } - if (max.HasValue && value > max.Value) - { - return max.Value; - } - return value; - } - - public static double SafeDivide(double lhs, double rhs, double fallback) - { - if (!IsVerySmall(rhs)) - { - return lhs / rhs; - } - return fallback; - } - } -} diff --git a/EleCho.WpfSuite/Themes/Generic.xaml b/EleCho.WpfSuite/Themes/Generic.xaml deleted file mode 100644 index be8b8bb3a5..0000000000 --- a/EleCho.WpfSuite/Themes/Generic.xaml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/EleCho.WpfSuite/ValueConverters/FallbackConverter.cs b/EleCho.WpfSuite/ValueConverters/FallbackConverter.cs deleted file mode 100644 index 89aaf17e78..0000000000 --- a/EleCho.WpfSuite/ValueConverters/FallbackConverter.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Globalization; -using System.Windows; - -namespace EleCho.WpfSuite -{ - /// - /// Fallback between multiple values, return the first non-null value - /// - public class FallbackConverter : SingletonMultiValueConverterBase - { - /// - public override object? Convert(object?[] values, Type targetType, object? parameter, CultureInfo culture) - { - foreach (var value in values) - { - if (value is not null && - value != DependencyProperty.UnsetValue) - return value; - } - - return null; - } - } -} - diff --git a/EleCho.WpfSuite/ValueConverters/MultiValueConverterBase.cs b/EleCho.WpfSuite/ValueConverters/MultiValueConverterBase.cs deleted file mode 100644 index 63489213ad..0000000000 --- a/EleCho.WpfSuite/ValueConverters/MultiValueConverterBase.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Globalization; -using System.Windows.Data; - -namespace EleCho.WpfSuite -{ - /// - /// Base class of multi value converter - /// - /// - public abstract class MultiValueConverterBase : IMultiValueConverter - { - /// - public abstract object? Convert(object?[] values, Type targetType, object? parameter, CultureInfo culture); - - /// - public virtual object?[] ConvertBack(object? value, Type[] targetTypes, object? parameter, CultureInfo culture) - { - throw new NotSupportedException(); - } - } -} diff --git a/EleCho.WpfSuite/ValueConverters/SingletonMultiValueConverterBase.cs b/EleCho.WpfSuite/ValueConverters/SingletonMultiValueConverterBase.cs deleted file mode 100644 index b436fcbebb..0000000000 --- a/EleCho.WpfSuite/ValueConverters/SingletonMultiValueConverterBase.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace EleCho.WpfSuite -{ - /// - /// Base class of singleton multi value converter - /// - /// - public abstract class SingletonMultiValueConverterBase : MultiValueConverterBase - where TSelf : SingletonMultiValueConverterBase, new() - { - private static TSelf? _instance = null; - - /// - /// Get an instance of - /// - public static TSelf Instance => _instance ?? new(); - } -} diff --git a/ILSpy.sln b/ILSpy.sln index 8efa6d216d..be813f458c 100644 --- a/ILSpy.sln +++ b/ILSpy.sln @@ -38,7 +38,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ICSharpCode.ILSpyX", "ICSha EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ICSharpCode.BamlDecompiler", "ICSharpCode.BamlDecompiler\ICSharpCode.BamlDecompiler.csproj", "{81A30182-3378-4952-8880-F44822390040}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EleCho.WpfSuite", "EleCho.WpfSuite\EleCho.WpfSuite.csproj", "{486469B9-51AF-43D0-ABCE-F5FA7E5FBE4C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibScrollingOptimization", "LibScrollingOptimization\LibScrollingOptimization.csproj", "{376D29B0-38FE-4517-A1A2-A54FBFEFF56C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -102,10 +102,10 @@ Global {81A30182-3378-4952-8880-F44822390040}.Debug|Any CPU.Build.0 = Debug|Any CPU {81A30182-3378-4952-8880-F44822390040}.Release|Any CPU.ActiveCfg = Release|Any CPU {81A30182-3378-4952-8880-F44822390040}.Release|Any CPU.Build.0 = Release|Any CPU - {486469B9-51AF-43D0-ABCE-F5FA7E5FBE4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {486469B9-51AF-43D0-ABCE-F5FA7E5FBE4C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {486469B9-51AF-43D0-ABCE-F5FA7E5FBE4C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {486469B9-51AF-43D0-ABCE-F5FA7E5FBE4C}.Release|Any CPU.Build.0 = Release|Any CPU + {376D29B0-38FE-4517-A1A2-A54FBFEFF56C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {376D29B0-38FE-4517-A1A2-A54FBFEFF56C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {376D29B0-38FE-4517-A1A2-A54FBFEFF56C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {376D29B0-38FE-4517-A1A2-A54FBFEFF56C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ILSpy/Controls/ZoomScrollViewer.cs b/ILSpy/Controls/ZoomScrollViewer.cs index 1b1400b43d..6466de0525 100644 --- a/ILSpy/Controls/ZoomScrollViewer.cs +++ b/ILSpy/Controls/ZoomScrollViewer.cs @@ -30,7 +30,7 @@ namespace ICSharpCode.ILSpy.Controls { - public class ZoomScrollViewer : EleCho.WpfSuite.ScrollViewer + public class ZoomScrollViewer : ScrollViewer { static ZoomScrollViewer() { @@ -108,7 +108,7 @@ static void CalculateZoomButtonCollapsed(DependencyObject d, DependencyPropertyC z.ComputedZoomButtonCollapsed = (z.AlwaysShowZoomButtons == false) && (z.CurrentZoom == 1.0); } - protected override void OnMouseWheel(MouseWheelEventArgs e) + protected override void OnPreviewMouseWheel(MouseWheelEventArgs e) { if (!e.Handled && Keyboard.Modifiers == ModifierKeys.Control && MouseWheelZoom) { @@ -165,7 +165,8 @@ protected override void OnMouseWheel(MouseWheelEventArgs e) e.Handled = true; } - base.OnMouseWheel(e); + + base.OnPreviewMouseWheel(e); } internal static double RoundToOneIfClose(double val) diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index 0b9d1dc040..369c124995 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -84,9 +84,9 @@ - + diff --git a/ILSpy/MainWindow.xaml b/ILSpy/MainWindow.xaml index 0d236371fb..823f25bd65 100644 --- a/ILSpy/MainWindow.xaml +++ b/ILSpy/MainWindow.xaml @@ -21,6 +21,8 @@ xmlns:b="http://schemas.microsoft.com/xaml/behaviors" xmlns:themes="clr-namespace:ICSharpCode.ILSpy.Themes" xmlns:toms="urn:TomsToolbox" + xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors" + xmlns:scroll="clr-namespace:LibScrollingOptimization;assembly=LibScrollingOptimization" d:DataContext="{d:DesignInstance local:MainWindowViewModel}" > @@ -34,6 +36,9 @@ AllowDropOrder="True" AllowDrop="True" BorderThickness="0" Visibility="Visible"> + + + - - + + @@ -57,12 +61,12 @@ - + - + \ No newline at end of file diff --git a/ILSpy/Options/DisplaySettingsPanel.xaml b/ILSpy/Options/DisplaySettingsPanel.xaml index 49395c3b23..a568d7591d 100644 --- a/ILSpy/Options/DisplaySettingsPanel.xaml +++ b/ILSpy/Options/DisplaySettingsPanel.xaml @@ -7,12 +7,16 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:themes="clr-namespace:ICSharpCode.ILSpy.Themes" - xmlns:ws="https://schemas.elecho.dev/wpfsuite" + xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors" + xmlns:scroll="clr-namespace:LibScrollingOptimization;assembly=LibScrollingOptimization" d:DataContext="{d:DesignInstance local:DisplaySettingsViewModel}"> - + + + + - + \ No newline at end of file diff --git a/ILSpy/Search/SearchPane.xaml b/ILSpy/Search/SearchPane.xaml index 25d21236d7..ecab67df04 100644 --- a/ILSpy/Search/SearchPane.xaml +++ b/ILSpy/Search/SearchPane.xaml @@ -4,7 +4,8 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:properties="clr-namespace:ICSharpCode.ILSpy.Properties" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" x:Name="self" mc:Ignorable="d" - xmlns:ws="https://schemas.elecho.dev/wpfsuite" + xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors" + xmlns:scroll="clr-namespace:LibScrollingOptimization;assembly=LibScrollingOptimization" d:DesignHeight="300" d:DesignWidth="300"> @@ -40,11 +41,11 @@ - - + diff --git a/ILSpy/TextView/DecompilerTextView.xaml b/ILSpy/TextView/DecompilerTextView.xaml index 2230cae602..bec4510f9d 100644 --- a/ILSpy/TextView/DecompilerTextView.xaml +++ b/ILSpy/TextView/DecompilerTextView.xaml @@ -1,13 +1,15 @@  + xmlns:themes="clr-namespace:ICSharpCode.ILSpy.Themes" + xmlns:scrolling="clr-namespace:LibScrollingOptimization;assembly=LibScrollingOptimization"> @@ -81,7 +83,11 @@ Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" - TextOptions.TextFormattingMode="{Binding CurrentZoom, ElementName=PART_ScrollViewer, Converter={x:Static local:ZoomLevelToTextFormattingModeConverter.Instance}}" /> + TextOptions.TextFormattingMode="{Binding CurrentZoom, ElementName=PART_ScrollViewer, Converter={x:Static local:ZoomLevelToTextFormattingModeConverter.Instance}}" > + + + + diff --git a/LibScrollingOptimization/LibScrollingOptimization.csproj b/LibScrollingOptimization/LibScrollingOptimization.csproj new file mode 100644 index 0000000000..a058d91637 --- /dev/null +++ b/LibScrollingOptimization/LibScrollingOptimization.csproj @@ -0,0 +1,14 @@ + + + + net8.0-windows7 + enable + enable + true + + + + + + + diff --git a/EleCho.WpfSuite/Utilities/ScrollViewerUtils.cs b/LibScrollingOptimization/ScrollViewerUtils.cs similarity index 98% rename from EleCho.WpfSuite/Utilities/ScrollViewerUtils.cs rename to LibScrollingOptimization/ScrollViewerUtils.cs index 88f3f6023b..10eee15763 100644 --- a/EleCho.WpfSuite/Utilities/ScrollViewerUtils.cs +++ b/LibScrollingOptimization/ScrollViewerUtils.cs @@ -3,7 +3,7 @@ using System.Windows.Controls; using System.Windows.Controls.Primitives; -namespace EleCho.WpfSuite +namespace LibScrollingOptimization { /// /// ScrollViewer Utilities diff --git a/EleCho.WpfSuite/Controls/ScrollViewer.cs b/LibScrollingOptimization/SmoothScrollingBehavior.cs similarity index 77% rename from EleCho.WpfSuite/Controls/ScrollViewer.cs rename to LibScrollingOptimization/SmoothScrollingBehavior.cs index ca0c820dbc..e49a1cb59e 100644 --- a/EleCho.WpfSuite/Controls/ScrollViewer.cs +++ b/LibScrollingOptimization/SmoothScrollingBehavior.cs @@ -3,29 +3,41 @@ using System.Diagnostics; using System.Linq; using System.Reflection; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; -using System.Windows.Data; -using System.Windows.Documents; using System.Windows.Input; -using System.Windows.Interop; -using System.Windows.Media; using System.Windows.Media.Animation; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; -namespace EleCho.WpfSuite +using TomsToolbox.Wpf; +using TomsToolbox.Wpf.Interactivity; + +namespace LibScrollingOptimization { - /// - public class ScrollViewer : System.Windows.Controls.ScrollViewer + /// + /// + /// + public class SmoothScrollingBehavior : FrameworkElementBehavior { - static ScrollViewer() + private ScrollViewer? _scrollViewer; + private ScrollContentPresenter? _scrollContentPresenter; + + private delegate bool GetBool(ScrollViewer scrollViewer); + private static readonly GetBool _propertyHandlesMouseWheelScrollingGetter; + private static readonly IEasingFunction _scrollingAnimationEase = new CubicEase() { EasingMode = EasingMode.EaseOut }; + private const long _millisecondsBetweenTouchpadScrolling = 100; + + private bool _animationRunning = false; + private int _lastScrollDelta = 0; + private int _lastVerticalScrollingDelta = 0; + private int _lastHorizontalScrollingDelta = 0; + private long _lastScrollingTick; + + static SmoothScrollingBehavior() { - DefaultStyleKeyProperty.OverrideMetadata(typeof(ScrollViewer), new FrameworkPropertyMetadata(typeof(ScrollViewer))); #if NETCOREAPP _propertyHandlesMouseWheelScrollingGetter = typeof(ScrollViewer) @@ -40,42 +52,67 @@ static ScrollViewer() #endif } - private delegate bool GetBool(ScrollViewer scrollViewer); - private static readonly GetBool _propertyHandlesMouseWheelScrollingGetter; - private static readonly IEasingFunction _scrollingAnimationEase = new CubicEase() { EasingMode = EasingMode.EaseOut }; - private const long _millisecondsBetweenTouchpadScrolling = 100; + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "get_ScrollInfo")] + static extern IScrollInfo GetScrollInfo(ScrollViewer scrollViewer); - private bool _animationRunning = false; - private int _lastScrollDelta = 0; - private int _lastVerticalScrollingDelta = 0; - private int _lastHorizontalScrollingDelta = 0; - private long _lastScrollingTick; + /// + protected override void OnAssociatedObjectLoaded() + { + base.OnAssociatedObjectLoaded(); + + _scrollViewer = AssociatedObject.VisualDescendantsAndSelf().OfType().FirstOrDefault(); - private FrameworkElement? _scrollContentPresenter; + if (_scrollViewer == null) + return; - /// - public override void OnApplyTemplate() + _scrollViewer.PreviewMouseWheel += ScrollViewer_PreviewMouseWheel; + _scrollContentPresenter = _scrollViewer.VisualDescendants().OfType().FirstOrDefault(); + } + + /// + protected override void OnAssociatedObjectUnloaded() { - base.OnApplyTemplate(); + base.OnAssociatedObjectUnloaded(); + + if (_scrollViewer == null) + return; - _scrollContentPresenter = GetTemplateChild("PART_ScrollContentPresenter") as FrameworkElement; + _scrollViewer.PreviewMouseWheel -= ScrollViewer_PreviewMouseWheel; + } + + + private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e) + { + if (!ScrollWithWheelDelta) + { + return; + } + else + { + Debug.WriteLine(e.Delta); + + CoreScrollWithWheelDelta(e); + } } private void CoreScrollWithWheelDelta(MouseWheelEventArgs e) { + if (_scrollViewer == null || _scrollContentPresenter == null) + return; + if (e.Handled) { return; } if (!AlwaysHandleMouseWheelScrolling && - !_propertyHandlesMouseWheelScrollingGetter.Invoke(this)) + !_propertyHandlesMouseWheelScrollingGetter.Invoke(_scrollViewer)) { return; } - bool vertical = ExtentHeight > 0; - bool horizontal = ExtentWidth > 0; + bool vertical = _scrollViewer.ExtentHeight > 0; + bool horizontal = _scrollViewer.ExtentWidth > 0; var tickCount = Environment.TickCount; var isTouchpadScrolling = @@ -99,31 +136,31 @@ private void CoreScrollWithWheelDelta(MouseWheelEventArgs e) if (vertical) { - if (ScrollInfo is IScrollInfo scrollInfo) + if (GetScrollInfo(_scrollViewer) is IScrollInfo scrollInfo) { // 考虑到 VirtualizingPanel 可能是虚拟的大小, 所以这里需要校正 Delta - scrollDelta *= scrollInfo.ViewportHeight / (_scrollContentPresenter?.ActualHeight ?? ActualHeight); + scrollDelta *= scrollInfo.ViewportHeight / (_scrollContentPresenter?.ActualHeight ?? _scrollViewer.ActualHeight); } var sameDirectionAsLast = Math.Sign(e.Delta) == Math.Sign(_lastVerticalScrollingDelta); - var nowOffset = sameDirectionAsLast && _animationRunning ? VerticalOffsetTarget : VerticalOffset; + var nowOffset = sameDirectionAsLast && _animationRunning ? VerticalOffsetTarget : _scrollViewer.VerticalOffset; var newOffset = nowOffset - scrollDelta; if (newOffset < 0) newOffset = 0; - if (newOffset > ScrollableHeight) - newOffset = ScrollableHeight; + if (newOffset > _scrollViewer.ScrollableHeight) + newOffset = _scrollViewer.ScrollableHeight; SetValue(VerticalOffsetTargetPropertyKey, newOffset); - BeginAnimation(ScrollViewerUtils.VerticalOffsetProperty, null); + _scrollViewer.BeginAnimation(ScrollViewerUtils.VerticalOffsetProperty, null); if (!EnableScrollingAnimation || isTouchpadScrolling) { - ScrollToVerticalOffset(newOffset); + _scrollViewer.ScrollToVerticalOffset(newOffset); } else { - var diff = newOffset - VerticalOffset; + var diff = newOffset - _scrollViewer.VerticalOffset; var absDiff = Math.Abs(diff); var duration = ScrollingAnimationDuration; if (absDiff < Mouse.MouseWheelDeltaForOneLine) @@ -134,45 +171,45 @@ private void CoreScrollWithWheelDelta(MouseWheelEventArgs e) DoubleAnimation doubleAnimation = new DoubleAnimation() { EasingFunction = _scrollingAnimationEase, Duration = duration, - From = VerticalOffset, + From = _scrollViewer.VerticalOffset, To = newOffset, }; doubleAnimation.Completed += DoubleAnimation_Completed; _animationRunning = true; - BeginAnimation(ScrollViewerUtils.VerticalOffsetProperty, doubleAnimation, HandoffBehavior.SnapshotAndReplace); + _scrollViewer.BeginAnimation(ScrollViewerUtils.VerticalOffsetProperty, doubleAnimation, HandoffBehavior.SnapshotAndReplace); } _lastVerticalScrollingDelta = e.Delta; } else if (horizontal) { - if (ScrollInfo is IScrollInfo scrollInfo) + if (GetScrollInfo(_scrollViewer) is IScrollInfo scrollInfo) { // 考虑到 VirtualizingPanel 可能是虚拟的大小, 所以这里需要校正 Delta - scrollDelta *= scrollInfo.ViewportWidth / (_scrollContentPresenter?.ActualWidth ?? ActualWidth); + scrollDelta *= scrollInfo.ViewportWidth / (_scrollContentPresenter?.ActualWidth ?? _scrollViewer.ActualWidth); } var sameDirectionAsLast = Math.Sign(e.Delta) == Math.Sign(_lastHorizontalScrollingDelta); - var nowOffset = sameDirectionAsLast && _animationRunning ? HorizontalOffsetTarget : HorizontalOffset; + var nowOffset = sameDirectionAsLast && _animationRunning ? HorizontalOffsetTarget : _scrollViewer.HorizontalOffset; var newOffset = nowOffset - scrollDelta; if (newOffset < 0) newOffset = 0; - if (newOffset > ScrollableWidth) - newOffset = ScrollableWidth; + if (newOffset > _scrollViewer.ScrollableWidth) + newOffset = _scrollViewer.ScrollableWidth; SetValue(HorizontalOffsetTargetPropertyKey, newOffset); - BeginAnimation(ScrollViewerUtils.HorizontalOffsetProperty, null); + _scrollViewer.BeginAnimation(ScrollViewerUtils.HorizontalOffsetProperty, null); if (!EnableScrollingAnimation || isTouchpadScrolling) { - ScrollToHorizontalOffset(newOffset); + _scrollViewer.ScrollToHorizontalOffset(newOffset); } else { - var diff = newOffset - HorizontalOffset; + var diff = newOffset - _scrollViewer.HorizontalOffset; var absDiff = Math.Abs(diff); var duration = ScrollingAnimationDuration; if (absDiff < Mouse.MouseWheelDeltaForOneLine) @@ -183,14 +220,14 @@ private void CoreScrollWithWheelDelta(MouseWheelEventArgs e) DoubleAnimation doubleAnimation = new DoubleAnimation() { EasingFunction = _scrollingAnimationEase, Duration = duration, - From = HorizontalOffset, + From = _scrollViewer.HorizontalOffset, To = newOffset, }; doubleAnimation.Completed += DoubleAnimation_Completed; _animationRunning = true; - BeginAnimation(ScrollViewerUtils.HorizontalOffsetProperty, doubleAnimation, HandoffBehavior.SnapshotAndReplace); + _scrollViewer.BeginAnimation(ScrollViewerUtils.HorizontalOffsetProperty, doubleAnimation, HandoffBehavior.SnapshotAndReplace); } _lastHorizontalScrollingDelta = e.Delta; @@ -207,21 +244,6 @@ private void DoubleAnimation_Completed(object? sender, EventArgs e) _animationRunning = false; } - /// - protected override void OnMouseWheel(MouseWheelEventArgs e) - { - if (!ScrollWithWheelDelta) - { - base.OnMouseWheel(e); - } - else - { - Debug.WriteLine(e.Delta); - - CoreScrollWithWheelDelta(e); - } - } - /// /// The horizontal offset of scrolling target /// @@ -297,13 +319,13 @@ public bool AlwaysHandleMouseWheelScrolling { /// The key needed set a read-only property /// public static readonly DependencyPropertyKey HorizontalOffsetTargetPropertyKey = - DependencyProperty.RegisterReadOnly(nameof(HorizontalOffsetTarget), typeof(double), typeof(ScrollViewer), new PropertyMetadata(0.0)); + DependencyProperty.RegisterReadOnly(nameof(HorizontalOffsetTarget), typeof(double), typeof(SmoothScrollingBehavior), new PropertyMetadata(0.0)); /// /// The key needed set a read-only property /// public static readonly DependencyPropertyKey VerticalOffsetTargetPropertyKey = - DependencyProperty.RegisterReadOnly(nameof(VerticalOffsetTarget), typeof(double), typeof(ScrollViewer), new PropertyMetadata(0.0)); + DependencyProperty.RegisterReadOnly(nameof(VerticalOffsetTarget), typeof(double), typeof(SmoothScrollingBehavior), new PropertyMetadata(0.0)); /// /// The key needed set a read-only property @@ -405,40 +427,40 @@ public static void SetAlwaysHandleMouseWheelScrolling(DependencyObject obj, bool /// The DependencyProperty of property. /// public static readonly DependencyProperty ScrollWithWheelDeltaProperty = - DependencyProperty.RegisterAttached(nameof(ScrollWithWheelDelta), typeof(bool), typeof(ScrollViewer), + DependencyProperty.RegisterAttached(nameof(ScrollWithWheelDelta), typeof(bool), typeof(SmoothScrollingBehavior), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits)); /// /// The DependencyProperty of property. /// public static readonly DependencyProperty EnableScrollingAnimationProperty = - DependencyProperty.RegisterAttached(nameof(EnableScrollingAnimation), typeof(bool), typeof(ScrollViewer), + DependencyProperty.RegisterAttached(nameof(EnableScrollingAnimation), typeof(bool), typeof(SmoothScrollingBehavior), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits)); /// /// The DependencyProperty of property. /// public static readonly DependencyProperty ScrollingAnimationDurationProperty = - DependencyProperty.RegisterAttached(nameof(ScrollingAnimationDuration), typeof(Duration), typeof(ScrollViewer), + DependencyProperty.RegisterAttached(nameof(ScrollingAnimationDuration), typeof(Duration), typeof(SmoothScrollingBehavior), new FrameworkPropertyMetadata(new Duration(TimeSpan.FromMilliseconds(250)), FrameworkPropertyMetadataOptions.Inherits), ValidateScrollingAnimationDuration); /// /// The DependencyProperty of property /// public static readonly DependencyProperty AlwaysHandleMouseWheelScrollingProperty = - DependencyProperty.RegisterAttached(nameof(AlwaysHandleMouseWheelScrolling), typeof(bool), typeof(ScrollViewer), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits)); + DependencyProperty.RegisterAttached(nameof(AlwaysHandleMouseWheelScrolling), typeof(bool), typeof(SmoothScrollingBehavior), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits)); /// /// The DependencyProperty of property /// public static readonly DependencyProperty MouseScrollDeltaFactorProperty = - DependencyProperty.Register(nameof(MouseScrollDeltaFactor), typeof(double), typeof(ScrollViewer), new PropertyMetadata(1.0)); + DependencyProperty.Register(nameof(MouseScrollDeltaFactor), typeof(double), typeof(SmoothScrollingBehavior), new PropertyMetadata(1.0)); /// /// The DependencyProperty of property /// public static readonly DependencyProperty TouchpadScrollDeltaFactorProperty = - DependencyProperty.Register(nameof(TouchpadScrollDeltaFactor), typeof(double), typeof(ScrollViewer), new PropertyMetadata(1.0)); + DependencyProperty.Register(nameof(TouchpadScrollDeltaFactor), typeof(double), typeof(SmoothScrollingBehavior), new PropertyMetadata(1.0)); private static bool ValidateScrollingAnimationDuration(object value) => value is Duration duration && duration.HasTimeSpan; diff --git a/SharpTreeView/ICSharpCode.TreeView.csproj b/SharpTreeView/ICSharpCode.TreeView.csproj index 45eca3a621..b59e5fde51 100644 --- a/SharpTreeView/ICSharpCode.TreeView.csproj +++ b/SharpTreeView/ICSharpCode.TreeView.csproj @@ -25,8 +25,4 @@ - - - - diff --git a/SharpTreeView/SharpTreeView.cs b/SharpTreeView/SharpTreeView.cs index bf2268c128..d4de0673da 100644 --- a/SharpTreeView/SharpTreeView.cs +++ b/SharpTreeView/SharpTreeView.cs @@ -30,7 +30,7 @@ namespace ICSharpCode.TreeView { - public class SharpTreeView : EleCho.WpfSuite.ListView + public class SharpTreeView : ListView { static SharpTreeView() { diff --git a/SharpTreeView/Themes/Generic.xaml b/SharpTreeView/Themes/Generic.xaml index 9bb6146f7f..8e32911f18 100644 --- a/SharpTreeView/Themes/Generic.xaml +++ b/SharpTreeView/Themes/Generic.xaml @@ -86,15 +86,15 @@ BorderThickness="1" BorderBrush="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" Padding="0 1 2 0"> - +
- -