Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lazy loading of listbox images from isolated storage

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?

like image 861
Heinrich Ulbricht Avatar asked May 29 '11 21:05

Heinrich Ulbricht


2 Answers

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()).

like image 180
Anheledir Avatar answered Oct 23 '22 07:10

Anheledir


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.

like image 42
Damian Antonowicz Avatar answered Oct 23 '22 05:10

Damian Antonowicz