12-31-2012 10:37 AM - edited 12-31-2012 10:37 AM
This is my code.... Which make me angry...
After clear() and repopulate() the CheckBox keep the user change.... So, if you check true, clear the list , and repopulate, the checkbox keep true.... What the hell ?? ListItemComponent doesn't destroy ??
12-31-2012 02:04 PM
The underlying issue comes from the fact that the visual items (whatever is defined inside ListItemComponent, in this case a single Checkbox) are created independently of the model items, and are reused. If the list shows only 10 items out of 50 (for example), it pre-creates approximately 20 CheckBox objects, so extras are available quickly during scrolling. As you scroll through the list, and the visual items are scrolled off the top and no longer visible, it caches those items and jumps them down just below the visible area of the list, then slides them into view after updating their state (name and checked state, in the case of a CheckBox) from the appropriate model data.
In the code as shown, when you toggle the CheckBox, the "checked" state is never being stored back to the model, nor is it being set from the model data in the first place, so if a checked item happens to get reused later on in the list during scrolling, it may appear already checked.
Here's code that's been instrumented to better show the relationship between the visual items (shown with #nn) and the items corresponding to the model data, as well as to properly handle changes to the state of the checkboxes by storing the data back to the model. Note that the ListView will programmatically change the state of the checkboxes as it reuses them during scrolling, so you also have to check the ListItem.initialized property so you know when to actually respond to the checkbox state changes in the handler (i.e. only when it's actual user input causing the change).
import bb.cascades 1.0
Page {
Container {
ListView {
dataModel: ArrayDataModel {
id: model
}
listItemComponents: [
ListItemComponent {
property int visid: 0
Container {
id: iroot
property string visid
leftPadding: 10
rightPadding: 10
layout: StackLayout {
orientation: LayoutOrientation.LeftToRight
}
Label {
preferredWidth: 100
verticalAlignment: VerticalAlignment.Center
text: visid
}
CheckBox {
text: ListItemData.name
checked: ListItemData.checked
onCheckedChanged: {
if (!iroot.ListItem.initialized)
return;
var item = ListItemData;
item.checked = checked;
print(iroot.visid, iroot.ListItem.indexPath,
'check', item.name, item.checked);
iroot.ListItem.view.dataModel.replace(
iroot.ListItem.indexPath, item);
}
onTextChanged: {
var item = ListItemData;
print(iroot.visid, iroot.ListItem.indexPath,
' text', item.name, item.checked);
}
}
onCreationCompleted: {
visid = '#' + (++iroot.ListItem.component.visid);
}
}
}
]
}// ListView
Button {
text: "populate"
onClicked: {
for (var i = 0; i < 60; i++) {
model.append({name: 'foobar ' + i, checked: false});
}
}
}
Button {
text: "clear"
onClicked: model.clear();
}
}// Container
}// Page