Skip to content

Commit 4569526

Browse files
Unregister hooks in ScrollViewerAssist when the ScrollViewer is unloaded (#3133)
* Unregister hooks when the ScrollViewer is unloaded * Use weak events to manage hooks
1 parent 1c7c4a3 commit 4569526

File tree

1 file changed

+53
-51
lines changed

1 file changed

+53
-51
lines changed

MaterialDesignThemes.Wpf/ScrollViewerAssist.cs

Lines changed: 53 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ public static bool GetShowSeparators(DependencyObject element)
7171
private static readonly DependencyProperty HorizontalScrollHookProperty = DependencyProperty.RegisterAttached(
7272
"HorizontalScrollHook", typeof(HwndSourceHook), typeof(ScrollViewerAssist), new PropertyMetadata(null));
7373

74+
private static readonly DependencyProperty HorizontalScrollSourceProperty = DependencyProperty.RegisterAttached(
75+
"HorizontalScrollSource", typeof(HwndSource), typeof(ScrollViewerAssist), new PropertyMetadata(null));
76+
7477
public static readonly DependencyProperty SupportHorizontalScrollProperty = DependencyProperty.RegisterAttached(
7578
"SupportHorizontalScroll", typeof(bool), typeof(ScrollViewerAssist), new PropertyMetadata(false, OnSupportHorizontalScrollChanged));
7679

@@ -79,50 +82,49 @@ private static void OnSupportHorizontalScrollChanged(DependencyObject d, Depende
7982
//Based on: https://blog.walterlv.com/post/handle-horizontal-scrolling-of-touchpad-en.html
8083
if (d is ScrollViewer scrollViewer)
8184
{
82-
if ((bool)e.NewValue)
85+
if (scrollViewer.IsLoaded)
8386
{
84-
OnLoaded(scrollViewer, sv =>
85-
{
86-
if (GetSupportHorizontalScroll(sv))
87-
{
88-
RegisterHook(sv);
89-
}
90-
});
87+
DoOnLoaded(scrollViewer);
9188
}
9289
else
9390
{
94-
OnLoaded(scrollViewer, sv =>
95-
{
96-
if (!GetSupportHorizontalScroll(sv))
97-
{
98-
RemoveHook(sv);
99-
}
100-
});
91+
WeakEventManager<ScrollViewer, RoutedEventArgs>.AddHandler(scrollViewer, nameof(ScrollViewer.Loaded), OnLoaded);
92+
WeakEventManager<ScrollViewer, RoutedEventArgs>.AddHandler(scrollViewer, nameof(ScrollViewer.Unloaded), OnUnloaded);
10193
}
10294
}
10395

104-
static void OnLoaded(ScrollViewer scrollViewer, Action<ScrollViewer> doOnLoaded)
96+
static void OnLoaded(object? sender, RoutedEventArgs e)
10597
{
106-
if (scrollViewer.IsLoaded)
98+
if (sender is ScrollViewer sv)
99+
{
100+
DoOnLoaded(sv);
101+
}
102+
}
103+
104+
static void DoOnLoaded(ScrollViewer sv)
105+
{
106+
if (GetSupportHorizontalScroll(sv))
107107
{
108-
doOnLoaded(scrollViewer);
108+
RegisterHook(sv);
109109
}
110110
else
111111
{
112-
RoutedEventHandler? onLoaded = null;
113-
onLoaded = (_, _) =>
114-
{
115-
scrollViewer.Loaded -= onLoaded;
116-
doOnLoaded(scrollViewer);
117-
};
118-
scrollViewer.Loaded += onLoaded;
112+
RemoveHook(sv);
113+
}
114+
}
115+
116+
static void OnUnloaded(object? sender, RoutedEventArgs e)
117+
{
118+
if (sender is ScrollViewer sv)
119+
{
120+
RemoveHook(sv);
119121
}
120122
}
121123

122124
static void RemoveHook(ScrollViewer scrollViewer)
123125
{
124126
if (scrollViewer.GetValue(HorizontalScrollHookProperty) is HwndSourceHook hook &&
125-
PresentationSource.FromVisual(scrollViewer) is HwndSource source)
127+
scrollViewer.GetValue(HorizontalScrollSourceProperty) is HwndSource source)
126128
{
127129
source.RemoveHook(hook);
128130
scrollViewer.SetValue(HorizontalScrollHookProperty, null);
@@ -135,6 +137,7 @@ static void RegisterHook(ScrollViewer scrollViewer)
135137
if (PresentationSource.FromVisual(scrollViewer) is HwndSource source)
136138
{
137139
HwndSourceHook hook = Hook;
140+
scrollViewer.SetValue(HorizontalScrollSourceProperty, source);
138141
scrollViewer.SetValue(HorizontalScrollHookProperty, hook);
139142
source.AddHook(hook);
140143
}
@@ -166,43 +169,42 @@ private static void OnBubbleVerticalScrollChanged(DependencyObject d, Dependency
166169
{
167170
if (d is ScrollViewer scrollViewer)
168171
{
169-
if ((bool)e.NewValue)
172+
if (scrollViewer.IsLoaded)
170173
{
171-
OnLoaded(scrollViewer, sv =>
172-
{
173-
if (GetBubbleVerticalScroll(sv))
174-
{
175-
RegisterHook(sv);
176-
}
177-
});
174+
DoOnLoaded(scrollViewer);
178175
}
179176
else
180177
{
181-
OnLoaded(scrollViewer, sv =>
182-
{
183-
if (!GetBubbleVerticalScroll(sv))
184-
{
185-
RemoveHook(sv);
186-
}
187-
});
178+
WeakEventManager<ScrollViewer, RoutedEventArgs>.AddHandler(scrollViewer, nameof(ScrollViewer.Loaded), OnLoaded);
179+
WeakEventManager<ScrollViewer, RoutedEventArgs>.AddHandler(scrollViewer, nameof(ScrollViewer.Unloaded), OnUnloaded);
188180
}
189181
}
190182

191-
static void OnLoaded(ScrollViewer scrollViewer, Action<ScrollViewer> doOnLoaded)
183+
static void OnLoaded(object? sender, RoutedEventArgs e)
192184
{
193-
if (scrollViewer.IsLoaded)
185+
if (sender is ScrollViewer sv)
194186
{
195-
doOnLoaded(scrollViewer);
187+
DoOnLoaded(sv);
188+
}
189+
}
190+
191+
static void DoOnLoaded(ScrollViewer sv)
192+
{
193+
if (GetBubbleVerticalScroll(sv))
194+
{
195+
RegisterHook(sv);
196196
}
197197
else
198198
{
199-
RoutedEventHandler? onLoaded = null;
200-
onLoaded = (_, _) =>
201-
{
202-
scrollViewer.Loaded -= onLoaded;
203-
doOnLoaded(scrollViewer);
204-
};
205-
scrollViewer.Loaded += onLoaded;
199+
RemoveHook(sv);
200+
}
201+
}
202+
203+
static void OnUnloaded(object? sender, RoutedEventArgs e)
204+
{
205+
if (sender is ScrollViewer sv)
206+
{
207+
RemoveHook(sv);
206208
}
207209
}
208210

0 commit comments

Comments
 (0)