-
Notifications
You must be signed in to change notification settings - Fork 133
/
EndOfScrollCommand.cs
116 lines (106 loc) · 4.56 KB
/
EndOfScrollCommand.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// ***********************************************************************
// <copyright file="EndOfScrollCommand.cs" company="Microsoft">
// Copyright (c) 2015 Microsoft. All rights reserved.
// </copyright>
// <summary></summary>
// ***********************************************************************
namespace AppStudio.Uwp.Commands
{
using System.Windows.Input;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using AppStudio.Uwp.Services;
/// <summary>
/// This class defines an attached property that can be used to attach a Command to a
/// ScrollViewer, allowing to bind any ICommand when end of scroll ends.
/// </summary>
public static class EndOfScrollCommand
{
/// <summary>
/// Definition for the attached property.
/// </summary>
private static DependencyProperty CommandProperty = DependencyProperty.RegisterAttached(
"Command",
typeof(ICommand),
typeof(EndOfScrollCommand),
new PropertyMetadata(null, OnCommandPropertyChanged));
/// <summary>
/// Sets a command into the attached property.
/// </summary>
/// <param name="dependencyObject">The dependency object to assign the command.</param>
/// <param name="value">The command to attach.</param>
public static void SetCommand(DependencyObject dependencyObject, ICommand value)
{
if (dependencyObject != null)
{
dependencyObject.SetValue(CommandProperty, value);
}
}
/// <summary>
/// Gets the command from the attached property.
/// </summary>
/// <param name="dependencyObject">The dependency object to query.</param>
/// <returns>The ICommand attached.</returns>
public static ICommand GetCommand(DependencyObject dependencyObject)
{
return dependencyObject == null ? null : (ICommand)dependencyObject.GetValue(CommandProperty);
}
/// <summary>
/// Handles the <see cref="E:CommandPropertyChanged" /> event.
/// </summary>
/// <param name="dependencyObject">The dependency object changed.</param>
/// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
private static void OnCommandPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var element = dependencyObject as FrameworkElement;
if (element != null)
{
element.Loaded -= ElementLoaded;
element.Loaded += ElementLoaded;
}
}
private static void ElementUnloaded(object sender, RoutedEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
element.Unloaded -= ElementUnloaded;
ScrollViewer scrollViewer = element.FindChildOfType<ScrollViewer>();
if (scrollViewer != null)
{
scrollViewer = null;
}
}
private static void ElementLoaded(object sender, RoutedEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
element.Loaded -= ElementLoaded;
ScrollViewer scrollViewer = element.FindChildOfType<ScrollViewer>();
if (scrollViewer != null)
{
var listener = new BindingListenerService();
listener.Changed += delegate
{
if (scrollViewer.ScrollableHeight > 0)
{
bool isAtBottom = scrollViewer.VerticalOffset >= scrollViewer.ScrollableHeight;
if (isAtBottom)
{
var command = GetCommand(element);
if (command != null && command.CanExecute(null))
{
command.Execute(null);
}
}
}
};
Binding binding = new Binding() { Source = scrollViewer, Path = new PropertyPath("VerticalOffset") };
listener.Attach(scrollViewer, binding);
element.Unloaded += ElementUnloaded;
}
else
{
System.Diagnostics.Debug.WriteLine("Error on EndOfScrollCommand: ScrollViewer not found.");
}
}
}
}