How do I get all get all selected indexes in a ListView?

I need to fetch all selected indexes for a ListView but the only thing available is…

  • .onSelectionChanged<List<object>>
  • .selectedIndex<int>
  • .selectedItem<object>

The only List here is the event callback, so I could track the objects there, but maintaining that separately and surviving a domain reload is irritating.

Is there no planned functionality for something like .selectedItems that can have built in persistence when using a ListView and SelectionType.Multiple?

There’s clearly persistence for the selected indexes since they survive reloads, but I can’t find it. Even the Documentation suggests that it is indeed tracked:

So I ended up just manually locally caching all of the selected objects each time .onSelectionChanged is called. To gain persistence I just used EditorPrefs to store the file paths to the selected objects and pull them back after assembly reload is complete.

It looks something like this:

        public void SelectAssets(List<object> objs)
        {
            Debug.Log("Selecting assets...");
            CurrentSelection = objs.ConvertAll(asset => (DataEntity)asset);
            StringBuilder sb = new StringBuilder();
            foreach (DataEntity assetFile in CurrentSelection)
            {
                sb.Append(AssetDatabase.GetAssetPath(assetFile) + "|");
            }

            EditorPrefs.SetString("Vault_SelectedAssets", sb.ToString());
            ChooseAsset(objs[0]);
        }
        private void GetSelectionPersistence()
        {
            string selected = EditorPrefs.GetString("Vault_SelectedAssets");
            if (selected == string.Empty) return;

            CurrentSelection = new List<DataEntity>();
            string[] split = selected.Split('|');
            foreach (string path in split)
            {
                if (path == string.Empty || path.Contains('|')) continue;
                CurrentSelection.Add(AssetDatabase.LoadAssetAtPath<DataEntity>(path));
                Debug.Log($"Pulling... ({path})");
            }
            Debug.Log($"Pulled persistence. {split.Length} items");
        }

Hope someone else finds this useful.

I also hope there is better List support in the future. This is quite an oversight of functionality - if functionality exists to select multiple things and there is built in support for selection persistence then it should be exposed properly.

Also note that from 2020.1 onward there’s a builtin ListView.selectedIndices: Unity - Scripting API: UIElements.ListView.selectedIndices

1 Like

Thanks for the heads up, Benoit. That’s great to hear =)