To use custom controls with UXML and UI Builder, you must expose them.
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> {}
// ...
}
定义该工厂后,就可以在 UXML 文件中使用 <StatusBar>
元素。
可为新类定义 UXML 特征,并将其工厂设置为使用这些特征。
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
有两个作用:
以上代码示例执行以下操作:
m_Status
的声明定义一个名为 status
的 XML 属性。uxmlChildElementsDescription
返回空的 IEnumerable
(表明 StatusBar
元素没有子项)。Init()
成员从 XML 解析器读取属性包中的 status
属性值,并将 StatusBar.status
属性设置为此值。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. |
UxmlAssetAttributeDescription<T> |
A string that represents an asset. |
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));
}
}
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# 文件的根级别(在任何命名空间之外)完成。
架构生成系统会执行以下操作:
<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.