Hi!
I modified Unity’s sample ListVIew
code to add new elements to a ListView
in runtime on UI Toolkit.
When the user clicks on the button, the code adds a new element to items
list
Everything works, but the items do not show on my ListView
UNTIL I resize my “Game” viewport.
How do I force the UI to update?
Here’s some prints:
-
After clicking the button a bunch of times:
-
After resizing the “Game” viewport:
Here’s the code:
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEditor;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UIElements;
using Random = UnityEngine.Random;
public class UIDemoController : MonoBehaviour
{
public VisualTreeAsset ListItem;
private VisualElement root;
private List<string> items;
private ListView listView;
void Start()
{
// ListItem = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/UI/Demo/item.uxml");
root = GetComponent<UIDocument>().rootVisualElement;
var btn = root.Q<Button>("add-new-item");
btn.clicked += AddNewItem;
// Create some list of data, here simply numbers in interval [1, 1000]
// const int itemCount = 5;
items = new List<string>();
// for (int i = 1; i <= itemCount; i++)
// items.Add(i.ToString());
// The "makeItem" function will be called as needed
// when the ListView needs more items to render
Func<VisualElement> makeItem = () => ListItem.CloneTree();
// As the user scrolls through the list, the ListView object
// will recycle elements created by the "makeItem"
// and invoke the "bindItem" callback to associate
// the element with the matching data item (specified as an index in the list)
Action<VisualElement, int> bindItem = (e, i) =>
{
e.Q<Label>("CharacterName").text = items[i];
e.Q<VisualElement>("bg").style.backgroundColor = new StyleColor(GetRandomColor());
};
listView = root.Q<ListView>();
listView.makeItem = makeItem;
listView.bindItem = bindItem;
listView.itemsSource = items;
listView.selectionType = SelectionType.Multiple;
// Callback invoked when the user double clicks an item
listView.onItemsChosen += Debug.Log;
// Callback invoked when the user changes the selection inside the ListView
listView.onSelectionChange += Debug.Log;
}
void AddNewItem()
{
Debug.Log("Clicked");
items.Add((items.Count + 1).ToString());
// listView.itemsSource = items;
// listView.visible = !listView.visible;
}
Color GetRandomColor()
{
var r = Random.Range(0f, 1f);
var g = Random.Range(0f, 1f);
var b = Random.Range(0f, 1f);
return new Color(r, g, b, 1f);
}
}