locked
Custom GroupDataSource RRS feed

  • Question

  • Hi,

    we have implemented a custom ListDataAdapter and use it with a VirtualizedDataSource. Now we'd like to display the data from that data source in a grouped ListView.

    One option we found is WinJS.UI.computeDataSourceGroups(), but the migration white paper says that it is not the best way to do it, because it won't scale well. Instead, it recommends to "create a corresponding group data source". This data source "should enumerate the list of groups, with all the data for the group header etc." and needs to have "A key field which matches to the groupKey on the items" and "A firstItemIndex property that is the overall index of the first item in the group".

    That is pretty much all the info we found. We tried to create a group data source as follows, adding 'groupKey' properties to the items returned by the original data source -- without any luck.

    list = new WinJs.Binding.List([
      { key: 'g1', title: 'Group1', firstItemIndex: 0 },
      { key: 'g2', title: 'Group2', firstItemIndex: 0 }
    ]);
    groupDataSource = list.dataSource;

    It would be great if there was some more documentation on how to build a custom groupDataSource. Or maybe there already is a code sample that I have missed?

    Cheers,

    Guido

    Thursday, March 1, 2012 1:59 PM

All replies

  • This should give you a good start:

    http://msdn.microsoft.com/en-us/library/windows/apps/hh770849.aspx


    Jeff Sanders (MSFT)

    Friday, March 2, 2012 1:56 PM
    Moderator
  • Hi Jeff,

    thank you for the link. It does not answer our question, though.

    We have already implemented an IListDataAdapter and created a VirtualizedDataSource with it -- as described in the linked document. We use this data source successfully as the itemDataSource of a ListView. The document does not explain how to implement a corresponding data source that can be used as the groupDataSource of a ListView. Is there any documentation on the latter?

    For now we use WinJS.UI.computeDataSourceGroups() to automatically create such a groupDataSource, but as mentioned in the original post, this is not the recommended way. Even worse, the data source created by WinJS.UI.computeDataSourceGroups() does not work correctly for us: Sometimes it will call the groupKey function over and over again for all elements and never display anything, which might be a bug in the WinJS implementation.

    Cheers,

    Guido

    Friday, March 2, 2012 2:25 PM
  • Hi Guido,

    Ah,

    How about the createGrouped method.  Would that work for you?

    http://msdn.microsoft.com/en-us/library/windows/apps/hh465464.aspx

    -Jeff


    Jeff Sanders (MSFT)

    Friday, March 2, 2012 2:42 PM
    Moderator
  • Hi Jeff,

    unfortunately, no.

    createGrouped() is method of WinJS.Binding.List. We are not using the dataSource property of a WinJS.Binding.List, but a custom data source derived from WinJS.UI.VirtualizedDataSource, that uses a custom IListDataAdapter (as described in the link you posted). To group the data from such a data source in a ListView, the Migration Whitepaper suggests to either use WinJS.UI.computeDataSourceGroups() (though it is not recommended, and sometimes shows erroneous behavior in our case), or to implement another custom data source (which we did not manage to do because of the scarce documentation).

    To sum things up, we'd like to know either

    • why WinJS.UI.computeDataSourceGroups() does not work as expected (it keeps calling groupKey function over and over again) or
    • how to implement a custom groupDataSource to work around the issue.

    Guido

    Friday, March 2, 2012 3:12 PM
  • I will get back to you after further research on this.

    -Jeff


    Jeff Sanders (MSFT)

    Friday, March 2, 2012 3:18 PM
    Moderator
  • In case it helps, this is what our IListDataAdapter implementation looks like (more or less, I removed code related to the NotificationHandler):

        function QueryDataAdapter(query) {
          this._query = query;
        }
    
        QueryDataAdapter.prototype.getCount = function() {
          var _this = this;
          return new WinJS.Promise(function(complete) {
            return _this._query.count(function(count) {
              return complete(count);
            });
          });
        };
    
        QueryDataAdapter.prototype.itemsFromIndex = function(requestIndex, countBefore, countAfter) {
          var fetchCount, fetchIndex,
            _this = this;
          fetchCount = countBefore + 1 + countAfter;
          fetchIndex = requestIndex - countBefore;
          return new WinJS.Promise(function(complete) {
            return _this._query.count(function(totalCount) {
              return _this._query.skip(fetchIndex).limit(fetchCount).list(function(objects) {
                var items = [];
                for (var _i = 0, _len = objects.length; _i < _len; _i++) {
                  var item = items[_i];
                  items.push({
                    key: item.id,
                    data: item
                  });
                }
                return complete({
                  items: items,
                  offset: requestIndex - fetchIndex,
                  absoluteIndex: requestIndex,
                  totalCount: totalCount
                });
              });
            });
          });
        };
    

    Friday, March 2, 2012 3:34 PM
  • I just discovered something: It seems like all items of one group need to have consecutive indices in the data source. I.e. it works, when the data looks like this:

    [object1 (group1), object2 (group1), object3 (group2)]

    But it does not work when the data looks like this:

    [object1 (group1), object2 (group1), object3 (group2), object4 (group1)]

    So, it seems like a group is just one consecutive range in the original data. For us, that would mean we can only group our data when it is already grouped, which seems a bit strange.

    Friday, March 2, 2012 4:25 PM
  • Without building your project it is difficult to tell what is going on.  Are you sure you are returnining the correct thing in your adapter (have you traced through debugging)?

    If you want me to look further into this you can contact me here and I can arrange to have you send me a simplified repro of the issue in a project.

    http://blogs.msdn.com/jpsanders/contact.aspx

    -Jeff


    Jeff Sanders (MSFT)

    Monday, March 5, 2012 8:47 PM
    Moderator
  • @gdoo Did you ever resolve this? I'm running into the same problem. I suspect that I am going to have to implement IListDataSource myself (VirtualizedDataSource throws an error because something internal does not implement fromKey.)
    Friday, August 3, 2012 11:12 PM
  • So, is there an example then as to how to display a virtualized data source as a grouped list view? Also, it looks like the order of items in a VirtualizedDataSource cannot be manipulated after the data was downloaded from a remote server (e.g. can't call moveToStart, moveToEnd, etc). I can understand as to why this may be (it's complicated to do that on a remote source), but I just want to confirm that it doesn't actually support that.

    Thanks

    Thursday, November 1, 2012 2:40 AM
  • this was never solved. Waiting for a sample app from MSFT that actually uses a virtualized datasource with grouping. Think its not possible.
    Monday, November 12, 2012 10:16 PM
  • I have the same problem, is there an example show that how to create a grouped list view from virtualized data source?
    • Edited by ppco Tuesday, December 17, 2013 9:16 AM
    Tuesday, December 17, 2013 9:16 AM