Simple *Get-Started on Scrollview*?

Here’s a functional EditorWindow using a data-bound ListView with customized items (simple labels) and buttons to create / delete / clear the list.

<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
    <ui:ListView focusable="True" selection-type="Multiple" reorderable="true" item-height="16" name="items" show-bound-collection-size="false" style="flex-grow: 1;" />
    <ui:VisualElement style="flex-direction: row; justify-content: flex-end;">
        <ui:Button text="+" name="items-add" tooltip="Add new item." />
        <ui:Button text="-" name="items-delete" tooltip="Delete selected items." />
        <ui:Button text="Clear" name="items-clear" tooltip="Clear all items." />
    </ui:VisualElement>
</ui:UXML>
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;

[EditorWindowTitle(title = "Item Library")]
public class ItemLibrary : EditorWindow
{
    // using the window itself as an example container
    [SerializeField] private List<string> m_Items = new List<string>();
   
    private ListView m_ListView;
    private SerializedProperty m_ListProperty;
    [MenuItem("Testing/Item Library")]
    public static void ShowExample()
    {
        GetWindow<ItemLibrary>().Show();
    }
    public void OnEnable()
    {
        var root = rootVisualElement;
       
        // instantiate the window UI
        var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/ItemLibrary/ItemLibrary.uxml");
        visualTree.CloneTree(root);

        var listView = root.Q<ListView>("items");

        var dataContext = new SerializedObject(this);
        var listProperty = dataContext.FindProperty(nameof(m_Items));
       
        // bind this ListView to the m_Items list
        listView.BindProperty(listProperty);
       
        // important, otherwise the item at index 0 is expected to bind to the Array.size property
        listView.showBoundCollectionSize = false;
       
        // customize the list items look and feel
        // note: if you don't set these callbacks, PropertyField will be used to bind each list item
        listView.makeItem = MakeItem;
        listView.bindItem = BindItem;

        m_ListView = listView;
        m_ListProperty = listProperty;

        var addButton = root.Q<Button>("items-add");
        addButton.clicked += AddItem;
       
        var deleteButton = root.Q<Button>("items-delete");
        deleteButton.clicked += DeleteSelectedItems;
       
        var clearButton = root.Q<Button>("items-clear");
        clearButton.clicked += ClearItems;
    }

    private void ClearItems()
    {
        Undo.RecordObject(this, "Clear items");
        m_Items.Clear();
    }

    private void DeleteSelectedItems()
    {
        if (!m_ListView.selectedIndices.Any())
            return;
       
        Undo.RecordObject(this, "Remove selected items");
        foreach (var selectedIndex in m_ListView.selectedIndices.OrderByDescending(i => i))
        {
            m_Items.RemoveAt(selectedIndex);
        }
    }

    private void AddItem()
    {
        Undo.RecordObject(this, "Add new item");
        m_Items.Add("Item " + m_Items.Count);
    }

    private VisualElement MakeItem()
    {
        // TODO: instantiate some UXML template here
        return new Label();
    }

    private void BindItem(VisualElement target, int index)
    {
        var bindable = (BindableElement)target;
        bindable.BindProperty(m_ListProperty.GetArrayElementAtIndex(index));
    }
}