Lazy loading of listbox images from isolated storage
Asked Answered
S

2

6

I have lots of images stored in isolated storage and want to display them in a listbox. However, I don't want all images to be loaded right away but lazily. So only when the user scrolls to see new items the images should be loaded. I also want to use data binding for providing the list item's data and image.

In the tests I did all images always got loaded right away and at once, so I am unsure whether this lazy loading can be achieved with the default ListBox and data binding. Can it?

Sang answered 29/5, 2011 at 21:48 Comment(1)
You can check this blog and the channel9 video discussing the same. Source code is also available. channel9.msdn.com/Shows/SilverlightTV/… jobijoy.blogspot.com/2011/05/…Sterilize
A
7

You can use the standard ListBox to "lazy load" your items with databinding. The keyword here is "data virtualization". You have to implement IList to the class you want to databind. The indexer method will only be called for the items currently visible and for the next calculated ~2 screens. This is also the reason you should use a fixed size grid for your item-layout, not a stackpanel with a calculated height based on all containing items (performance!).

You don't have to implement all IList members, just a few. Here is an example:

    public class MyVirtualList : IList {
    private List<string> tmpList;

    public MyVirtualList(List<string> mydata) {
        tmpList = new List<string>();
        if (mydata == null || mydata.Count <= 0) return;
        foreach (var item in mydata)
            tmpList.Add(item);
    }

    public int Count {
        get { return tmpList != null ? tmpList.Count : 0; }
    }

    public object this[int index] {
        get {
            Debug.WriteLine("Just requested item #" + index);
            return tmpList[index];
        }
        set {
            throw new NotImplementedException();
        }
    }

    public int IndexOf(object value) {
        return tmpList.IndexOf(value as string);
    }

    public int Add(object value) {
        tmpList.Add(value as string);
        return Count - 1;
    }

    #region not implemented methods
    public void Clear() {
        throw new NotImplementedException();
    }

    public bool Contains(object value) {
        throw new NotImplementedException();
    }

    public void Insert(int index, object value) {
        throw new NotImplementedException();
    }

    public bool IsFixedSize {
        get { throw new NotImplementedException(); }
    }

    public bool IsReadOnly {
        get { throw new NotImplementedException(); }
    }

    public void Remove(object value) {
        throw new NotImplementedException();
    }

    public void RemoveAt(int index) {
        throw new NotImplementedException();
    }

    public void CopyTo(Array array, int index) {
        throw new NotImplementedException();
    }

    public bool IsSynchronized {
        get { throw new NotImplementedException(); }
    }

    public object SyncRoot {
        get { throw new NotImplementedException(); }
    }

    public IEnumerator GetEnumerator() {
        throw new NotImplementedException();
    }
    #endregion
}

While debugging you can see that not all items are loaded at once but only when needed (see Debug.WriteLine()).

Aliphatic answered 30/5, 2011 at 7:55 Comment(3)
That's genious, thanks! Works perfect. The keyword really is "data virtualization" - googling it brought me to the page of Shawn Oster who also elaborates a bit on the topic: shawnoster.com/blog/post/…Sang
And just for the record: I did not bind to an IList in the first place, I bound to a List. Replacing this List with the IList seems to be doing the trick.Sang
I know this was forever ago, but using an observable collection does the exact same thing yes?Persuasive
C
1

Check this LazyListBox implementation. This ListBox will load complex template for items visible on screen. For items not visible on screen you set simple template.

Cranston answered 29/5, 2011 at 21:54 Comment(1)
Thanks for the link, that's very interesting to read. For now the solution of Anheledir is enough for my purposes. But for the future I will keep an eye on the LazyListBox.Sang

© 2022 - 2024 — McMap. All rights reserved.