1
- using System . Windows ;
1
+ using System ;
2
+ using System . Windows ;
2
3
using System . Windows . Controls ;
4
+ using System . Windows . Interop ;
3
5
4
6
namespace MaterialDesignThemes . Wpf
5
7
{
@@ -69,5 +71,102 @@ public static bool GetShowSeparators(DependencyObject element)
69
71
public static void SetIgnorePadding ( DependencyObject element , bool value ) => element . SetValue ( IgnorePaddingProperty , value ) ;
70
72
public static bool GetIgnorePadding ( DependencyObject element ) => ( bool ) element . GetValue ( IgnorePaddingProperty ) ;
71
73
74
+ private static readonly DependencyProperty HorizontalScrollHookProperty = DependencyProperty . RegisterAttached (
75
+ "HorizontalScrollHook" , typeof ( HwndSourceHook ) , typeof ( ScrollViewerAssist ) , new PropertyMetadata ( null ) ) ;
76
+
77
+ public static readonly DependencyProperty SupportHorizontalScrollProperty = DependencyProperty . RegisterAttached (
78
+ "SupportHorizontalScroll" , typeof ( bool ) , typeof ( ScrollViewerAssist ) , new PropertyMetadata ( false , OnSupportHorizontalScrollChanged ) ) ;
79
+
80
+ private static void OnSupportHorizontalScrollChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
81
+ {
82
+ //Based on: https://blog.walterlv.com/post/handle-horizontal-scrolling-of-touchpad-en.html
83
+ if ( d is ScrollViewer scrollViewer )
84
+ {
85
+ if ( ( bool ) e . NewValue )
86
+ {
87
+ OnLoaded ( scrollViewer , sv =>
88
+ {
89
+ if ( GetSupportHorizontalScroll ( sv ) )
90
+ {
91
+ RegisterHook ( sv ) ;
92
+ }
93
+ } ) ;
94
+ }
95
+ else
96
+ {
97
+ OnLoaded ( scrollViewer , sv =>
98
+ {
99
+ if ( ! GetSupportHorizontalScroll ( sv ) )
100
+ {
101
+ RemoveHook ( sv ) ;
102
+ }
103
+ } ) ;
104
+ }
105
+ }
106
+
107
+ static void OnLoaded ( ScrollViewer scrollViewer , Action < ScrollViewer > doOnLoaded )
108
+ {
109
+ if ( scrollViewer . IsLoaded )
110
+ {
111
+ doOnLoaded ( scrollViewer ) ;
112
+ }
113
+ else
114
+ {
115
+ RoutedEventHandler ? onLoaded = null ;
116
+ onLoaded = ( _ , _ ) =>
117
+ {
118
+ scrollViewer . Loaded -= onLoaded ;
119
+ doOnLoaded ( scrollViewer ) ;
120
+ } ;
121
+ scrollViewer . Loaded += onLoaded ;
122
+ }
123
+ }
124
+
125
+ static void RemoveHook ( ScrollViewer scrollViewer )
126
+ {
127
+ if ( scrollViewer . GetValue ( HorizontalScrollHookProperty ) is HwndSourceHook hook &&
128
+ PresentationSource . FromVisual ( scrollViewer ) is HwndSource source )
129
+ {
130
+ source . RemoveHook ( hook ) ;
131
+ scrollViewer . SetValue ( HorizontalScrollHookProperty , null ) ;
132
+ }
133
+ }
134
+
135
+ static void RegisterHook ( ScrollViewer scrollViewer )
136
+ {
137
+ RemoveHook ( scrollViewer ) ;
138
+ if ( PresentationSource . FromVisual ( scrollViewer ) is HwndSource source )
139
+ {
140
+ HwndSourceHook hook = Hook ;
141
+ scrollViewer . SetValue ( HorizontalScrollHookProperty , hook ) ;
142
+ source . AddHook ( hook ) ;
143
+ }
144
+
145
+ IntPtr Hook ( IntPtr hwnd , int msg , IntPtr wParam , IntPtr lParam , ref bool handled )
146
+ {
147
+ const int WM_MOUSEHWHEEL = 0x020E ;
148
+ switch ( msg )
149
+ {
150
+ case WM_MOUSEHWHEEL :
151
+ int tilt = ( short ) ( ( wParam . ToInt32 ( ) >> 16 ) & 0xFFFF ) ;
152
+ OnMouseTilt ( tilt ) ;
153
+ return ( IntPtr ) 1 ;
154
+ }
155
+ return IntPtr . Zero ;
156
+ }
157
+
158
+ void OnMouseTilt ( int tilt )
159
+ {
160
+ scrollViewer . ScrollToHorizontalOffset ( scrollViewer . HorizontalOffset + tilt ) ;
161
+ }
162
+ }
163
+ }
164
+
165
+ public static void SetSupportHorizontalScroll ( DependencyObject element , bool value )
166
+ => element . SetValue ( SupportHorizontalScrollProperty , value ) ;
167
+
168
+ public static bool GetSupportHorizontalScroll ( DependencyObject element )
169
+ => ( bool ) element . GetValue ( SupportHorizontalScrollProperty ) ;
170
+
72
171
}
73
172
}
0 commit comments