[SOLVED] Making a ListView refresh

I cannot make a ListView refresh dynamically → Only if I Close/open window, or redraw entire UI, merely calling ListView.Refresh() does not appear to have any effect.
How would I go about and make a ListView Refresh/Redraw?

using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public class ListViewTest : EditorWindow
{
    [MenuItem("Test/ListViewTest")]
    public static void OpenDemoManual()
    {
        GetWindow<ListViewTest>().Show();
    }
    List<string> items;
    ListView listView;

    public void OnEnable()
    {
        SetupNewData();
        rootVisualElement.Add(listView);
    }

    void SetupNewData()
    {
        const int itemCount = 10;
        items = new List<string>(itemCount);
        for (int i = 1; i <= itemCount; i++)
            items.Add(i.ToString() + " " + UnityEngine.Random.value);

        SetupListView();
    }
    void SetupListView()
    {
        Func<VisualElement> makeItem = () => new Label();
        Action<VisualElement, int> bindItem = (e, i) => (e as Label).text = items[i];
        const int itemHeight = 16;
        listView = new ListView(items, itemHeight, makeItem, bindItem);
        listView.selectionType = SelectionType.Single;
        listView.onSelectionChanged += objects => SetupNewData();
        listView.style.flexGrow = 1.0f;

        Debug.Log("Now refreshing"); // This executes: When list is clicked, this is written in the console
        listView.Refresh(); // This does not do anything, the list is not updated, data are changed, but no refresh in UI?!?
    }
}

Oh, got it, the order was wrong, this works for demo, list updates with random numbers when clicked on:

using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public class ListViewTest : EditorWindow
{
    [MenuItem("Test/ListViewTest")]
    public static void OpenDemoManual()
    {
        GetWindow<ListViewTest>().Show();
    }
    List<string> items;
    ListView listView;

    public void OnEnable()
    {
        SetupNewData();
        rootVisualElement.Add(listView);
    }

    void SetupNewData()
    {
        const int itemCount = 10;
        items = new List<string>(itemCount);
        for (int i = 1; i <= itemCount; i++)
            items.Add(i.ToString() + " " + UnityEngine.Random.value);

        if (listView != null)
        {
            listView.Refresh();
        }
        else
        {
            SetupListView();
        }
    }
    void SetupListView()
    {
        Func<VisualElement> makeItem = () => new Label();
        Action<VisualElement, int> bindItem = (e, i) => (e as Label).text = items[i];
        const int itemHeight = 16;
        listView = new ListView(items, itemHeight, makeItem, bindItem);
        listView.selectionType = SelectionType.Single;
        listView.onSelectionChanged += objects => SetupNewData();
        listView.style.flexGrow = 1.0f;
    }
}

Hello,
I’m doing something similar to your example, but in my case, the number of items is different on every call. And I’m getting a
“ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.” exception.
Any idea?

1 Like

Ever solve this?

1 Like

I don`t know if we are experiencing the same problem, but for my case it was reassigning the same array to itemsSource of list view. No rebuild or refresh items needed, they did not work on their own anyway.

2 Likes