Listview is not displaing anything in CustomEditor

After trying for 3 days now to figure out why in the flying **** the listview wont work I ask for some guidance; I’ve made a test project to give the new UIToolkit a look and see what is can do, I’m somewhat impressed by somethings and the ease of using it over the old system, so good job so far but I have one gigantic complaint that currently makes me wanna pull my hairs out; and that is the listview.

I’ve setup a test editor like this:

    EditorTest m_BindingsTestObject;
    VisualElement root;

    public override VisualElement CreateInspectorGUI()
    {
        root = new VisualElement();

        m_BindingsTestObject = (EditorTest)target;

        const int itemCount = 1000;
        var items = new List<string>(itemCount);
        for (int i = 1; i <= itemCount; i++)
            items.Add(i.ToString());
       
        Func<VisualElement> makeItem = () => new Label();
        Action<VisualElement, int> bindItem = (e, i) => (e as Label).text = (m_BindingsTestObject._testerarraylist[i] != null ? m_BindingsTestObject._testerarraylist[i].name : "NULL");

        ListView lv = new ListView();
        lv.itemsSource = m_BindingsTestObject._testerarraylist;
        lv.makeItem = makeItem;
        lv.bindItem = bindItem;
        lv.itemHeight = 32;
        root.Add(lv);
        lv.Refresh();
        return root;
    }

Heavily inspired by the samples, I then have a list in my script editortest like so:

    [SerializeField]
    public List<GameObjectCollection> _testerarraylist = new List<GameObjectCollection>();

and somehow my editor looks like this;
6210146--682358--upload_2020-8-16_17-13-46.png
If I go into debug mode I can clearly see that I have items in my list:
6210146--682361--upload_2020-8-16_17-15-5.png

  • Ignore other variables but the Testarraylist, also the Testarraylist is indeed a list of scriptable objects, the class for the scriptable object looks like this if it somehow have trouble with generics or scriptableobjects to display, which renders it completely useless to me:
    public class ObservableCollectionRef<T> : ScriptableObject, IEnumerable
    {
        [SerializeField]
        private List<T> _value;
        [SerializeField]
        GameEvent _onValueChangedEvent;
        public event OnCollectionChanged OnValueChanged;

        public void Reset()
        {
            _value = new List<T>();
        }

        public T this[int index]
        {
            get
            {
                return _value[index];
            }

            set
            {
                _value[index] = value;
                OnValueChanged?.Invoke();
                _onValueChangedEvent?.Invoke();
            }
        }

        public int Count
        {
            get
            {
                return _value.Count;
            }
        }

        public void Add(T value)
        {
            _value.Add(value);
            OnValueChanged?.Invoke();
            _onValueChangedEvent?.Invoke();
        }

        public void Clear()
        {
            _value.Clear();
            OnValueChanged?.Invoke();
            _onValueChangedEvent?.Invoke();
        }

        public bool Contains(T value)
        {
            return _value.Contains(value);
        }

        public void CopyTo(T[] array, int index)
        {
            _value.CopyTo(array, index);
        }

        public IEnumerator GetEnumerator()
        {
            return _value.GetEnumerator();
        }

        public int IndexOf(T value)
        {
            return _value.IndexOf(value);
        }

        public void Insert(int index, T value)
        {
            _value.Insert(index, value);
        }

        public void Remove(T value)
        {
            _value.Remove(value);
            OnValueChanged?.Invoke();
            _onValueChangedEvent?.Invoke();
        }

        public void RemoveAt(int index)
        {
            _value.RemoveAt(index);
            OnValueChanged?.Invoke();
            _onValueChangedEvent?.Invoke();
        }
    }

    public delegate void OnCollectionChanged();
   
    [CreateAssetMenu(menuName = "ScriptableObjects/GameObjectCollection")]
    public class GameObjectCollection : ObservableCollectionRef<GameObject>
    {
    }

I’ve furthermore already tried “BindProperty” and “Bind” without anyluck or result that differ from the images above and I’m starting to wonder rather or not I’m just dumb or if there actually are a bug at large somewhere, does anyone have any sugegstions on how I at least can get my list to display something?

Thanks a lot in regard!

You have to specify a height with ListView, not just itemHeight but listView.style.height = n;. It for some reason doesn’t follow layout rules fully even with flex grow set to 1 or greater. If you use the debugger you will see the height at 0, which I highly recommend using when things like this happen.

1 Like

I just tried it, and it works! pretty strange that it doesn’t auto resize, is there anyway I can make sure the height is equal to the sum of all the childrens in the listview?

Also if you by chance know this; How can I make the list reorderable? the “reorderable” property does not seem to do anything…

Thanks a lot for the help!

Simply take your collection size and multiply it by the item height.

Never tried to get it to work, it’s checked but it doesn’t do anything. Gotta give them some time, they are still working on it and not all features are implemented, like dynamic item sizes or new input system compatibility.

I noticed you said

So does this imply that I can’t dynamically change size of a single item in my list too lets say if I have a list of foldouts/toggles?

So while I get the system is still a newer thing at this point I do believe it is out of preview? and that seems to me like a huge over sight, but I guess I could just clone a tree element x amount of times although it sounds like this could negatively affact performance, but as mentioned before the listview still seems kinda useless in its current state, and that is said from someone who is used to the garbage listview in xamarin-forms :smile:

I’ve used it for quite a few things without problems. UITK is out of preview for the editor, not runtime. ListView is one of those components that still needs work yes, but to say its useless I don’t believe that. It actually has some good things going for it, like it reuses the elements that make up the items as you scroll, so its not just a whole bunch of elements with bad performance when you have a huge list.

It would be nice to have foldout style elements, but it’s not a deal breaker, it works and does so without the horrible lag that I would get from using ReorderableLists or uGUI’s ScrollView with lots of entries. I just hope they get it full featured in a reasonable amount of time. That being said though you can roll your own, as ListView is just a component built on top of a ScrollView. I’ll stick with ListView, it does what I need for now.

ListView should have been called VirtualizedListViewForVeryLargeDataSets, or something like that. It currently has a name that doesn’t express why it exists.

ListView is not a container you add elements into. It’s entire purpose is to create the elements for you (via makeItem), but only enough to fill the space it was given. It then re-uses (re-binds) these same elements as you scroll. It’s meant to handle thousands to data entries without creating thousands of UI elements that you will never see. This is why right now it needs an explicit size. It needs to know how many elements it can fit in it’s area. It’s also why it currently requires all items to have a fixed height, because that’s how it knows how many it can display and how many items to scroll when say going to the middle of the scroll bar.

This size problem is compounded by the fact that when ListView is used inside the Inspector, you cannot just tell it to stretch to all available space (via flex-grow: 1). This is because the entire Inspector is inside a ScrollView, which, has infinite internal size. Telling any element inside a ScrollView to “take all available space” won’t work.

I just wanted to give some background on why it is the way it is, but since we can’t really change the name of ListView at this point, we have no choice but to make it work as you expected it to. We’re working on that. They are simple problems with complicated solutions - the best kind.

For your use case, just create the Object Fields for each ScriptableObject, in a loop. They will take the space they need and everything is a lot simpler with no binding or make callbacks to set. You can even put them in a Foldout if you’d like.

PS: Not sure why the reordering is not working. Might be a bug.

4 Likes

Thanks for the explanation @uDamian , it makes more sense to me now. I hope it does to the op as well.

@uDamian very good explanation really appreciate it! With that explanation even tho Listview may have some short comings they make a lot of sense all the sudden!

Also sorry if this is something you’re getting asked all the times; but is there plans on supporting reorderable collections throug reorderablelists? :slight_smile:

Yes, it’s something fairly high in our backlog but I can’t say exactly when we’ll be on par with the IMGUI version of ReorderableList. ListView did learn to allow reordering of elements (apart from some bugs maybe) in 2020.2. We’ll be expanding on that in the 2021 release.

1 Like

Awesome, I see so much potential for this to really tweak and extend editors and make engine tool so I’m really wanting it to be great, sadly it it not html but the xaml like markup is great and I really hope UXML will not stray too far from how xaml in wpf, uwp and xamarin works :slight_smile:

Thanks. I’d forgotten this absurd bug in UIT, was scratching my head for “why is the official source code from Unity’s own manual completely failing to work?”.

  1. Copy from the docs
  2. Paste into source
  3. FAIL. No errors, just: Unity supplied source code they knew was broken-by-design

https://docs.unity3d.com/Packages/com.unity.ui@1.0/api/UnityEngine.UIElements.ListView.html - why has no-one fixed this in all the years it’s been known to be wrong? What’s the point of including source code you know can’t work?

It’s the same here https://docs.unity3d.com/ScriptReference/UIElements.ListView.html too. Unity has a bad track record of having wrong or incomplete info in the docs.

We’ve been investing a lot more than before into improving our docs. If you see issues with a docs page, please submit the feedback directly on the doc page, the “Report a problem on this page” link.

Also, good to double check the version of the docs matches the version of Unity you’re on. ListView’s API has changed in 2022 and you might get warnings/errors with 2021 ListView samples.

I’m sorry but: no. I submit many bugs, and many docs bugs, and the ‘report a problem on this page’ is completely useless.

Most of us have stopped using the report-a-doc-bug since Unity has been actively ignoring it for the last 2+ years - there are docs that I repeatedly submitted the same ‘this doc is wrong’ + text explaining how, even with copy/pastable corrections - and Unity did absolutely nothing, and no-one is ever held accountable because there’s no record it was ever reported. I cannot ‘prove’ I submitted anything - there is no paper trail.

By contrast: using the BugReporting Tool gets results, Unity teams actually act on it.

I tested this: I did two docs reports at same time, one via the ‘report a problem on this page’ link, the other via creating an empty UnityProject and using the BugReporter tool. The latter got a response and eventually fixed. The former … was still incorrect 1+ years later.

If you care about fixing a doc, it is (today) simply not worth using that ‘report a problem link’.

HOWEVER … more conceringly … If I remember correctly: it was revealed last month / two months (?) that Unity was largely retiring the ‘submit feedback on docs’ system, something to do with re-organizing the docs team / large redundancies that affected the docs teams? What I remember: being told to stop using the ‘report-a-docs problem’ button, because it wasn’t going to be maintained any more.

I have probably misremembered that - but I honestly wasn’t paying much attention since I (and many others) have long ago learned that the ‘report a bug on this page’ usually has no effect on anything.

Thanks for the reminder on this - UIT changes so much from version to version, and so many core things get no ‘backports’ that its important to check which doc version you’re looking at. Although code-samples shouldn’t generally break when moving from version to version!

However my observation over last few years is that ‘broken code samples’ in Unity docs (not just UIT, but UIT included) are nearly always ‘broken in all LTS + beta + alpha versions of Unity’. It’s usually ‘no-one tested this before publishing it’, rather than ‘someone changed the API and forgot to change the code-sample’.

I can remember some cases of the latter - although ironically the ones I can remember off the top of my head were nearly all caused by the UIToolkit team - but they are much less common. And the ones I can remember are all cases of “the code that changed is in a different part of Unity to the code-sample you’re looking at” (e.g. changes made by the Nested Prefabs team broke code in unrelated parts of Unity, or e.g. UIToolkit broke CustomPropertyDrawers for everyone and left the code samples in main Unity docs unusable, no warnings, just fully broken).

So I don’t think it’s much of a problem to be looking at wrong version of docs (when it comes to code samples).

It’s true that the feedback loop for when and how we address docs issues is not there. You don’t see what’s being fixed and your perception that we “ignore” the submitted feedback is understandable. It’s also true that historically we’ve under-invested in our docs, hence the 2-year+ old issues. That said, while I can’t comment on other parts of the manual, I work directly with the docs team responsible for the UI docs and I know they’ve fixed 100s of docs bugs in the last few weeks. We very much do not ignore those reports. I will try to see how we can better communicate this progress.

Very much not the case. I’ll try to find out if there’s some context behind this. We’ve not always been amazing at consistent communication so you may remember correctly. All I can say is that today, this is not the case, and we do look at all that feedback.

This comes back to our historically low investment in docs. The samples are now actively being worked on and maintained by dedicated staff. This problem should become less common as we move forward.

1 Like

IMHO if you want any buy-in from the community on this it’s critically important to surface this, visibly.

Ideally do what Google does: every submission tags the email address / user account of the submitter, and you auto-email them when their comment is acted upon (Google doesn’t let users track it, or see any info - there’s almost zero cost to Google, its trivial - but when you submit a bug in e.g. google maps you get an email days, months (or years) later when they finally fix it).

But if for some reason Unity’s unwilling as a corporation to do that, at least a publically visible record of “this quarter we had X bugs reported on docs, of which Y have been resolved, and Z rejected, with A postponed and B not yet read”. So that people can see there’s actual value in submitting the bugs.

Fully agree. I asked and we do have an work happening internally to surface this information.

1 Like