【Unity】【UI Toolkit】MultiColumnListViewを使って複数のカラムを持つリストビューを実装する

UnityのUI ToolkitでMultiColumnListViewを使ってマルチカラムのリストビューを実装する方法をまとめました。

Unity 2022.2.17

はじめに

UI ToolkitのListViewを使うと、下図のような複数のカラムを持ったリストビューを作成することができます。

マルチカラムリストビュー

本記事ではこのようなマルチカラムのリストビューを持ったEditorWindowの作り方についてまとめます。

UXMLファイルを作成する

まずUXMLファイルでレイアウトを作成します。
以下のようにMultiColumnListViewと、その中に二つのカラムを設定します。

<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:MultiColumnListView fixed-item-height="20">
        <ui:Columns>
            <ui:Column name="name" title="Name" width="80" />
            <ui:Column name="description" title="Description" width="80" />
        </ui:Columns>
    </ui:MultiColumnListView>
</ui:UXML>

これをeditor_layout.uxmlとして保存しておきます。

次にリストに表示する各項目のレイアウトを作成します。
といっても今回は単純にラベルを表示しているだけです。

<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:Label text="Label" />
</ui:UXML>

これをitem_layout.uxmlとして保存しておきます。

EditorWindowを作成する

次に以下の通りEditorWindowスクリプトを作成します。

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

public sealed class Example : EditorWindow
{
    [SerializeField] private VisualTreeAsset editorLayout;
    [SerializeField] private VisualTreeAsset labelItemLayout;
    private readonly List<Item> _items = new();

    private void Reset()
    {
        for (var i = 0; i < 100; i++)
            _items.Add(new Item { name = $"Item {i}", description = $"Description {i}" });
    }

    private void CreateGUI()
    {
        editorLayout.CloneTree(rootVisualElement);
        var multiColumnListView = rootVisualElement.Q<MultiColumnListView>();
        
        // itemsSourceにソースとなるリストを代入
        multiColumnListView.itemsSource = _items;
        
        var nameColumn = multiColumnListView.columns["name"];
        var descriptionColumn = multiColumnListView.columns["description"];
        
        // セルのレイアウトを作成する処理
        nameColumn.makeCell = labelItemLayout.CloneTree;
        descriptionColumn.makeCell = labelItemLayout.CloneTree;
        
        // セルの内容を設定する処理
        nameColumn.bindCell = (e, i) => e.Q<Label>().text = _items[i].name;
        descriptionColumn.bindCell = (e, i) => e.Q<Label>().text = _items[i].description;
    }

    [MenuItem("Window/Example")]
    public static void ShowWindow()
    {
        GetWindow<Example>();
    }

    [Serializable]
    public struct Item
    {
        public string name;
        public string description;
    }
}

説明はコメントに書いた通りです。

各セルに対してレイアウトを生成し、セルの内容をバインドできます。

実行結果

前節のスクリプトのInspectorからeditorLayouteditor_layout.uxmlを、labelItemLayoutitem_layout.uxmlアサインし、Window > Exampleからウィンドウを開くと以下の結果が得られます。

結果

正常に実装できていることを確認できました。

参考

docs.unity3d.com