问题
I've got ListBox bound to List. I want to load more items when scrolled to bottom of list so that some animation indicating loading is shown and bound list is expanded. If I understand correctly, I can use ObservableCollection instead of List and expand that collection. Also, I could wrap ItemPresenter into StackPanel with ItemPresenter and Image at bottom.
But how do I detect that list has been scrolled to bottom and initiate expanding of collection?
回答1:
Check tutorials:
- http://blog.slimcode.com/2010/09/11/detect-when-a-listbox-scrolls-to-its-end-wp7/
- http://danielvaughan.orpius.com/post/Scroll-Based-Data-Loading-in-Windows-Phone-7.aspx
回答2:
I found this http://blogs.microsoft.co.il/blogs/shair/archive/2011/04/06/wp7-how-to-extend-listbox-when-reaching-last-item.aspx in my opinion is more coincided, easy and self-explanatory than other examples.
回答3:
I'm use the following code to solve the same problem. As base I use the following solution, added one DependecyProperties and removed references on assembly Microsoft.Practices.Prism.Interactivity.
public class ScrollViewMonitor
{
public static readonly DependencyProperty ReachBottomCommandProperty = DependencyProperty.RegisterAttached("ReachBottomCommand",
typeof(ICommand), typeof(ScrollViewMonitor), new PropertyMetadata(null, ReachBottomCommandChanged));
public static ICommand GetReachBottomCommand(DependencyObject dpObj)
{
return (ICommand)dpObj.GetValue(ReachBottomCommandProperty);
}
public static void SetReachBottomCommand(DependencyObject dpObj, ICommand command)
{
dpObj.SetValue(ReachBottomCommandProperty, command);
}
private static FrameworkElement _frmElemenet;
private static void ReachBottomCommandChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
_frmElemenet = obj as FrameworkElement;
if (_frmElemenet != null)
_frmElemenet.Loaded += frmElement_Loaded;
}
public static readonly DependencyProperty VerticalOffsetProperty = DependencyProperty.RegisterAttached("VerticalOffset",
typeof(double), typeof(ScrollViewMonitor), new PropertyMetadata(0.0, VerticalOffsetChanged));
private static void VerticalOffsetChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
ScrollViewer scrollView = (ScrollViewer)obj;
if (scrollView.VerticalOffset > scrollView.ScrollableHeight * 0.8)
{
ICommand command = GetReachBottomCommand(_frmElemenet);
if (command != null)
command.Execute(null);
}
}
private static void frmElement_Loaded(object sender, RoutedEventArgs e)
{
FrameworkElement frmElement = (FrameworkElement)sender;
frmElement.Loaded -= frmElement_Loaded;
var scrollView = FindChildOfType<ScrollViewer>(frmElement);
if (scrollView != null)
scrollView.SetBinding(VerticalOffsetProperty, new Binding("VerticalOffset")
{
Source = scrollView
});
}
private static T FindChildOfType<T>(DependencyObject obj) where T : class
{
Queue<DependencyObject> queue = new Queue<DependencyObject>();
queue.Enqueue(obj); //Adds an object to the end of the
while (queue.Count > 0)
{
DependencyObject current = queue.Dequeue(); //Removes and returns the object at the beginning of the Queue
for (int i = 0, count = VisualTreeHelper.GetChildrenCount(current); i < count; i++)
{
DependencyObject dpObj = VisualTreeHelper.GetChild(current, 0);
T typeChild = dpObj as T;
if (typeChild != null)
return typeChild;
queue.Enqueue(dpObj); //Adds an object to the end of the Queue
}
}
return null;
}
}
In XAML
<ListBox x:Name="_lstBoxNews"
DataContext="{Binding Mode=OneTime}"
ItemsSource="{Binding Items, Mode=OneWay}"
ItemTemplate="{Binding Mode=OneWay, Source={StaticResource ShortArticleTemlate}}"
hlp:ScrollViewMonitor.ReachBottomCommand="{Binding LoadAdditionalArticles, Mode=OneTime}"
>
</ListBox>
来源:https://stackoverflow.com/questions/9958138/load-more-items-into-listbox-when-scrolled-to-bottom