Version: 2022.1
言語: 日本語
カスタムコントロールの作成
UXML のタグ名と属性のカスタマイズ

Expose custom control to UXML and UI Builder

To use custom controls with UXML and UI Builder, you must expose them.

Define a factory

To define new elements, derive a new class from VisualElement or one of its subclasses, and then implement the appropriate functionality within this new class.

Your new class must implement a default constructor. For example:

class StatusBar : VisualElement
{
    public StatusBar()
    {
        m_Status = String.Empty;
    }

    string m_Status;
    public string status { get; set; }
}

In order for UI Toolkit to instantiate a new class when it reads a UXML file, you must define a factory for your class. Unless your factory needs to do something special, you can derive the factory from UxmlFactory<T>. It’s recommended that you put the factory class within your component class.

For example, the following code snippet define a factory named UxmlFactory for the StatusBar class:

class StatusBar : VisualElement
{
    public new class UxmlFactory : UxmlFactory<StatusBar> {}

    // ...
}

この Factory を定義すると、UXML ファイルの <StatusBar> 要素を使用することができます。

Define attributes on elements

新しいクラスに UXML の特性 (traits) を定義し、その特性を使用するように Factory を設定することができます。

For example, the following code snippet defines a UXML traits class to initialize the status property as a property of the StatusBar class. The status property initializes from UXML data.

class StatusBar : VisualElement
{
    public new class UxmlFactory : UxmlFactory<StatusBar, UxmlTraits> {}

    public new class UxmlTraits : VisualElement.UxmlTraits
    {
        UxmlStringAttributeDescription m_Status = new UxmlStringAttributeDescription { name = "status" };

        public override IEnumerable<UxmlChildElementDescription> uxmlChildElementsDescription
        {
            get { yield break; }
        }

        public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
        {
            base.Init(ve, bag, cc);
            ((StatusBar)ve).status = m_Status.GetValueFromBag(bag, cc);
        }
    }

    // ...
}

UxmlTraits には 2 つの目的があります。

  • Factory は UxmlTraits を使って、新しく作られたオブジェクトを初期化します。
  • スキーマ生成処理によって UxmlTraits は分析され、要素に関する情報が取得されます。この情報は XML スキーマディレクティブに変換されます。

上のサンプルコードは以下の処理を行います。

  • m_Status の宣言は XML 属性 status を定義します。
  • uxmlChildElementsDescriptionStatusBar 要素に子がないことを示す空の IEnumerable を返します。
  • Init() メンバーは、XML パーサーからプロパティバッグの status 属性の値を読み込み、StatusBar.status プロパティにこの値に設定します。
  • The UxmlTraits class is placed inside the StatusBar class. This allows the Init() method to access the private members of StatusBar.
  • 新しい UxmlTraits クラスは基本クラス UxmlTraits を継承しているので、基本クラスの属性を共有します。
  • Init()base.Init() を呼び出して基本クラスのプロパティを初期化します。

The code example above declares a string attribute with the UxmlStringAttributeDescription class. UI Toolkit supports the following types of attributes and each links a C# type to a UMXL type:

属性 属性値
UxmlStringAttributeDescription 文字列
UxmlFloatAttributeDescription C# float 型の範囲の単精度浮動小数点値
UxmlDoubleAttributeDescription C# double 型の範囲の倍精度浮動小数点値
UxmlIntAttributeDescription C# int 型の範囲の整数値
UxmlLongAttributeDescription C# long 型の範囲の整数値
UxmlBoolAttributeDescription true または false
UxmlColorAttributeDescription A string that represents a color defined in USS format.
UxmlEnumAttributeDescription<T> A string that represents one of the values for the Enum type T.
UxmlTypeAttributeDescription<T> A string that represents the assembly-qualified name of the type.

In the code example above, the uxmlChildElementsDescription returns an empty IEnumerable which indicates that the StatusBar element doesn’t accept child element descriptions to the XML schema.

To have an element accept children of any type, you must override the uxmlChildElementsDescription property. For example, for the StatusBar element to accept children of any type, you must specify the uxmlChildElementsDescription property as follows:

public override IEnumerable<UxmlChildElementDescription> uxmlChildElementsDescription
{
    get
    {
        yield return new UxmlChildElementDescription(typeof(VisualElement));
    }
}

Define a namespace prefix

Once you have defined a new element in C#, you can use the element in your UXML files. To categorize elements, create your class in a namespace. When you define a new namespace, you can define a prefix for the namespace. You must define namespace prefixes as attributes of the root <UXML> element and replace the full namespace name when scoping elements.

To define a namespace prefix, add a UxmlNamespacePrefix attribute to your assembly for each namespace prefix. For example:

[assembly:UxmlNamespacePrefix( "My.First.Namespace"、 "first")]
[assembly:UxmlNamespacePrefix( "My.Second.Namespace"、 "second")]

これは、アセンブリの C# ファイルのルートレベル (任意の名前空間の外側) で行います。

スキーマ生成システムは以下を行います。

  • これらの属性を確認し、それらを使用してスキーマを生成します。
  • Adds the namespace prefix definition as an attribute of the <UXML> element in newly created UXML files.
  • xsi:schemaLocation 属性に名前空間のスキーマファイルの場所を含めます。

To ensure that your text editor recognizes the new element, select Assets > Update UXML Schema to update the schema definition.

To create a new UXML document with the prefix, select Assets > Create > UI Toolkit > UI Document.

その他の参考資料

カスタムコントロールの作成
UXML のタグ名と属性のカスタマイズ