I have a WP8 app where i have some items in the local db. I have two entities (for the purposes of this question) - folders and files. I want to display these in a listbox with a custom datatemplate. I select items from the localdb, create an observablecollection of modeltype that wraps both entity models (for unified representation) and then bind that to the listbox. This approach works great for results of the moderate numbers (e.g. up to 1000 items). However, for larger lists (e.g. 10K items) i get out of memory exception.
Further to that, even for 1k the performance is obviously not awesome as the algorithm is to basically create a new model for each entity fetched.
Is there any way to bind a listbox directly to a results of the query in the same way as NSFetchedResultsController operates? Update So as suggested in the comments, i tried loading data on-demand. However, as listbox is not virtualised, loading some 800 items into listbox by adding them to observable collection i end up with the Exit Code - 2147220978 (0x8004020e), suggesting that the graphical data just overloaded available resources. So i wrote some code to delete top items from observable collection when scrolling down, and all is great. However, trying to detect when user scrolls up is breaking everything. When scrolling down, i use linq to visual tree, grab hold of ScrollViewer and check if VerticalOffset is >= ScrollableHeight. But when checking if user scrolled to the top, i have to check for VerticalOffset == 0.0, but the DependencyPropertyListener i use will not raise any events if user is already at the top, even though my items were added.. e.g.:
var scrollViewer = (ScrollViewer)CurrentItemTiles.Descendants<ScrollViewer>().FirstOrDefault();
var listener = new DependencyPropertyListener();
listener.Changed += delegate(object o, BindingChangedEventArgs args)
{
if (scrollViewer.VerticalOffset >= scrollViewer.ScrollableHeight)
{ // scrolling down. This works well even when the user keeps holding the scroll bar down, e.g. scrolls through all pages.
LoadItems(Page + 1);
if (CurrentItems.Count > 200)
{
for (int i = 0; i <= 50; i++)
{
CurrentItems.RemoveAt(i);
}
}
}
else if (scrollViewer.VerticalOffset == 0.0 && Page > 4)
{
// This works well when the user is down below and they scroll up.
// If they want to keep going UP, they have to scroll down a little, then up again,
// and again and again. This doesnt feel natural at all.
var count = CurrentItems.Count - 1;
// second argument signifies that we will add items to the top of ObservableCollection<TModel>
LoadItems(Page - 4, true);
for (int i = 0; i <= 50; i++)
{
if (CurrentItems.Count >= (count + i)) CurrentItems.RemoveAt(count + i);
}
}
};
var binding = new Binding("VerticalOffset") { Source = scrollViewer };
listener.Attach(scrollViewer, binding);
User contributions licensed under CC BY-SA 3.0