Quick answer: BindItem must reset every visual aspect from the data model. Don’t store row state on the element — pooling reuses elements across indices. Track selection in data; render in BindItem.

Scroll a ListView; rows show wrong colors or selection state. The recycled element kept state from the previous index.

The Symptom

Scrolling reveals incorrect highlight, color, or sub-element values. State only matches data after a re-bind / refresh.

The Fix

listView.makeItem = () => new VisualElement();

listView.bindItem = (el, i) =>
{
    var data = items[i];
    el.Q<Label>("name").text = data.Name;
    el.EnableInClassList("selected", listView.selectedIndices.Contains(i));
    el.EnableInClassList("alert", data.HasAlert);
    el.RemoveFromClassList("hover");  // reset transient
};

listView.unbindItem = (el, i) =>
{
    // optional: clean up event subscriptions
};

Every visual aspect set explicitly. Class list reset. No leakage between rows.

Selection in Data

Use ListView’s selectedIndex and selectedIndices APIs. Don’t store “am I selected” on the element. BindItem queries the canonical selection state.

Verifying

Scroll the ListView. Rows should show correct state at each position. Without the fix: visible flicker between recycle events.

“Reset every aspect in BindItem. Selection in data. Pool reuses safely.”

Related Issues

For UI Toolkit USS @import, see USS @import. For dynamic styles, see dynamic styles.

Bind from data. Reset transient. Pool clean.