Here is my first attempt to achive a VariableSize List View in HTML /JS. I tried to apply the same concept as what I knew about XAML and the TemplateSelector, so I started with a function returning the right template, and finally I come to this satisfaying solution
I just made a first try to achieve this : http://sdrv.ms/Yosvcr
Instead of giving a Template to the ListView, I gave it a function that selects the right template according to the index of the item. Then you have different template, with different style, but all the items style have the same size. Then, if you read the end of this page, the paragraph about cell-spanning, you’ll see that you need to change two more things to achieve what you want : change the groupInfo or itemInfo properties of the GridLayout used in your ListView.
Here are the key parts of the sample I provided :
1/ First, you declare two or more templates + your listview:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| <div id="mediumListIconTextTemplate" data-win-control="WinJS.Binding.Template"> <div class="mediumItem"> <h4 data-win-bind="innerText: title"></h4> <h6 data-win-bind="innerText: text"></h6> </div></div><div id="largeListIconTextTemplate" data-win-control="WinJS.Binding.Template"> <div class="largeItem"> <h2 data-win-bind="innerText: title"></h2> <h3 data-win-bind="innerText: text"></h3> </div></div><div id="listView" data-win-control="WinJS.UI.ListView" data-win-options="{ itemDataSource: myData.items.dataSource, itemTemplate:myData.template, selectionMode: 'none', tapBehavior: 'none', swipeBehavior: 'none' }"></div> |
Then you can add some CSS :
1
2
3
4
5
6
7
8
9
10
11
| .mediumItem { width:100px; height:100px; background-color:cornflowerblue;}.largeItem { width:100px; height:150px; background-color:green;} |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
| (function () { "use strict"; // Create a new bindable list var list = new WinJS.Binding.List([]); // some fake data list.push({ title: "Titre 1", text: "Texte 1" }); list.push({ title: "Titre 2", text: "Texte 2" }); list.push({ title: "Titre 3", text: "Texte 3" }); list.push({ title: "Titre 4", text: "Texte 4" }); // my function that selects the template function selectTemplate(itemPromise) { // it receives a promise of an item return itemPromise.then(function (item) { // Then I can get the item // and based on its index property I can choose a templatE. var container = window.document.createElement("div"); var itemTemplate; switch (item.index) { case 0: itemTemplate = WinJS.Utilities.query("#mediumListIconTextTemplate")[0]; break; case 1: itemTemplate = WinJS.Utilities.query("#largeListIconTextTemplate")[0]; break; default: itemTemplate = WinJS.Utilities.query("#largeListIconTextTemplate")[0]; break; } // I put my item in a container and style it with the choosen template. itemTemplate.winControl.render(item.data, container); return container; }); } // The selection function has to be marked as supported for processing or you get an error. WinJS.Utilities.markSupportedForProcessing(selectTemplate); // declare the model and expose the selectTemplate function. WinJS.Namespace.define("myData", { items: list, template: selectTemplate });})(); |
So when the page gets processed by WinJS to display the controls :
1
2
3
4
5
6
7
8
9
10
11
12
13
| args.setPromise(WinJS.UI.processAll().then(function () { var listView = WinJS.Utilities.query('#listView')[0].winControl; listView.layout = new WinJS.UI.GridLayout; // Enable CellSpanning and give base size. listView.layout.groupInfo = function () { return { enableCellSpanning: true, cellWidth: 50, cellHeight: 50 }; } })); |