要将视觉元素的属性绑定到C#中的数据源,请创建一个DataSource
实例。使用此绑定类型,您可以直接在绑定实例上定义DataSource
和DataSourcePath
。
要在C#中创建运行时绑定,请按照以下步骤:
创建一个绑定。绑定是您可以通过唯一的ID创建,注册或注册视觉元素的对象。
定义数据源以及绑定对象的数据源路径。数据源是包含要绑定到的属性的对象。数据源路径是从数据源到您要绑定到的属性的相对路径。
定义绑定模式并更新触发器对于绑定对象。绑定模式定义了如何在数据源和 UI 之间复制变化。更新触发器定义何时更新绑定对象。
将绑定对象注册到视觉元素。
如有必要,添加类型转换器以在数据源和UI之间转换数据类型。
以下示例创建了一个绑定对象并将其注册到视觉元素。
var dataSource = ScriptableObject.CreateInstance<ExampleObject>();
var root = new VisualElement
{
name = "root",
dataSource = dataSource
};
var vector3Field = new Vector3Field("Vec3 Field");
vector3Field.SetBinding("label", new DataBinding
{
dataSourcePath = new PropertyPath(nameof(ExampleObject.vector3Label)),
bindingMode = BindingMode.ToTarget
});
vector3Field.SetBinding("value", new DataBinding
{
dataSourcePath = new PropertyPath(nameof(ExampleObject.vector3Value))
});
root.Add(vector3Field);
var floatField = new FloatField("Float Field") { value = 42.2f };
floatField.SetBinding("value", new DataBinding
{
dataSourcePath = new PropertyPath(nameof(ExampleObject.sumOfVector3Properties))
});
root.Add(floatField);
var label = new Label("Label")
{
dataSourcePath = new PropertyPath(nameof(ExampleObject.dangerLevel))
};
// Here, we do not need to set the dataSourcePath because we will only use two bindings and they will use the same path,
// so we set the dataSourcePath on the Label directly instead.
var binding = new DataBinding
{
bindingMode = BindingMode.ToTarget
};
// Add a custom float -> string converter
binding.sourceToUiConverters.AddConverter((ref float v) =>
{
return v switch
{
>= 0 and < 1.0f/3.0f => "Danger",
>= 1.0f/3.0f and < 2.0f/3.0f => "Neutral",
_ => "Good"
};
});
// Add a custom float -> StyleColor
binding.sourceToUiConverters.AddConverter((ref float v) => new StyleColor(Color.Lerp(Color.red, Color.green, v)));
// Since the binding is targeting the same data source property, we can reuse the same instance.
label.SetBinding("text", binding);
label.SetBinding("style.backgroundColor", binding);
root.Add(label);
它等同于以下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:VisualElement data-source="ExampleObject.asset" name="VisualElement" >
<ui:Vector3Field label="Vec3 Field">
<Bindings>
<ui:DataBinding property="label" data-source-path="vector3Label" binding-mode="ToSource" />
<ui:DataBinding property="value" data-source-path="vector3Value" />
</Bindings>
</ui:Vector3Field>
<ui:FloatField label="Float Field" value="42.2">
<Bindings>
<ui:DataBinding property="value" data-source-path="sumOfVector3Properties" binding-mode="ToTarget" />
</Bindings>
</ui:FloatField>
<ui:Label text="Label" data-source-path="dangerLevel">
<Bindings>
<ui:DataBinding property="text" binding-mode="ToTarget" source-to-ui-converters="Value To Progress" />
<ui:DataBinding property="style.backgroundColor" binding-mode="ToTarget" source-to-ui-converters="Value To Progress" />
</Bindings>
</ui:Label>
</ui:VisualElement>
</ui:UXML>
您可以使用以下方法来管理绑定对象:
您可以以与其他数据源相同的方式创建可绑定的属性,这意味着您也可以使用VisualElement
类型为数据源。一个VisualElement
类型和其他数据源是VisualElement
类型带有内置版本操作。您必须使用一个内置版本控制VisualElement
输入传播更改。
要报告更改,请致电NotifyPropertychanged
方法。此方法采用bindingId
这标识了更改的属性。
以下示例显示了如何报告一个更改VisualElement
类型:
// Creates a static readonly BindingId that is unique to this type. This is used to identify the property.
public static readonly BindingId intValueProperty = nameof(intValue);
private int m_IntValue;
[CreateProperty]
public int intValue
{
get => m_IntValue;
set
{
if (m_IntValue == value)
return;
m_IntValue = value;
// This instructs the binding system that a change occured.
NotifyPropertyChanged(intValueProperty);
}
}
遵循以下技巧和最佳实践来优化性能:
使用正确的绑定ID :绑定系统使用绑定ID来识别绑定对象和元素的目标属性。绑定ID必须是元素的目标属性。例如,如果您想绑定到value
属性Vector3Field
,绑定ID必须是Vector3Field.valueProperty
。
避免使用绑定的内部数据更新 :不要使用绑定来更新视觉元素的内部数据。例如,不要使用绑定来同步x
、y
和z
的子元素Vector3Field
。而是使用绑定来同步value
属性Vector3Field
与Vector3
数据源的属性。
UI工具包没有报告更改element.style
和element.resolvedStyle
。因此,您可以使用绑定实例来定位元素的分辨样式,但无法跟踪其更改。