I have a ListView that’s Bound to a list through a SerializedProperty. I want to only show a subset of the objects in the actual list, based on some filters.
As an example, say I have a list of Recipes, and I want to have a toggle to turn on/off showing recipes that I currently can make, or all recipes.
As far as I can tell, there’s no way to do this, but the enum member AlternatingRowBackground.ContentOnly that’s both available in the UI builder and the API implies that there’s ways to have rows with no content, but I can’t find a way to do that. Any ideas?
AlternatingRowBackground.ContentOnly only controls styling of the rows. ContentOnly just means the alternating row colors are applied to the content of the list and not the headers.
There’s no built-in filter for ListView. You’d have to filter the data source itself.
That’s what I did, but boy is that code ugly. If this was just a normal list of objects, it’d be fine, I’d make a new, filtered list, draw the list view for that, and then on adding/removing I’d add/remove in the original list.
That’s not as easy with SerializedProperties, as they’re not objects, they’re pseudo-pointers to array indices. If I take out a SerializedProperty with the propertyPath “myArray[3]”, and then remove element 2 from that array, my SerializedProperty is now pointing at a different, possibly out of bounds element.
So this means that for every mutation of the array, I have to either do very tedious counting to figure out which elements to keep, or rebuild the entire filter and ListView, which makes me wonder why I’m using a retained mode UI in the first place
If I could just have some way to tell the ListView “don’t draw this element”, either with a callback or by setting display=none on the VisualElement I get in my bindItem callback, then I could write a third as much code and achieve the same thing that I do with the manual filtering, with a lot less corners where bugs can live.
I think you could do that. You could have a List<VisualElement, int> where VisualElement is a bound list item and int is the index. On bindItem you bind the PropertyField, set its display property according to the current filter, and add it to the list. On unbindItem you unbind and remove from the list. Every time your filter changes, you go through every entry in the list and set its display property accordingly. The List could be a Dictionary to help to avoid duplicate entries by mistake.
The problem there is that even with display: none, you still get an empty list entry. At least you do that if you have the drag-and-drop handles, which I don’t really want for this case, I just hadn’t tried to take it out yet.