To bind a property of a visual elementA node of a visual tree that instantiates or derives from the C# VisualElement class. You can style the look, define the behaviour, and display it on screen as part of the UI. More info
See in Glossary to a data source in C#, create an instance of DataBinding. With this binding type, you can define a dataSource and a dataSourcePath directly on the binding instance.
To create a runtime binding in C#, follow these steps:
Assume you have a data source object named ExampleMultiPropertiesObject that contains a Vector3 property named vector3Value and a float property named sumOfVector3Properties, which is the sum of the x, y, and z components of the vector3Value property. For more information about this data source object, refer to the Create a data source asset section of the Bind to multiple properties with runtime binding example.
You can then create a binding object and register it to a visual element as follows:
using Unity.Properties;
using UnityEngine;
using UnityEngine.UIElements;
public class RuntimeBindingExample
{
public VisualElement CreateBindingExample()
{
var dataSource = ScriptableObject.CreateInstance<ExampleMultiPropertiesObject>();
var root = new VisualElement
{
name = "root",
dataSource = dataSource
};
var vector3Field = new Vector3Field("Vec3 Field");
vector3Field.SetBinding("value", new DataBinding
{
dataSourcePath = new PropertyPath(nameof(ExampleMultiPropertiesObject.vector3Value))
});
root.Add(vector3Field);
var floatField = new FloatField("Float Field") { value = 42.2f };
floatField.SetBinding("value", new DataBinding
{
dataSourcePath = new PropertyPath(nameof(ExampleMultiPropertiesObject.sumOfVector3Properties))
});
root.Add(floatField);
return root;
}
}
It’s equivalent to the following UXML:
<engine:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:engine="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<engine:VisualElement data-source="MulPropertyObject.asset" name="VisualElement" style="flex-grow: 1;">
<engine:Vector3Field label="Vec3 Field">
<Bindings>
<engine:DataBinding property="value" data-source-path="vector3Value" binding-mode="ToSource"/>
</Bindings>
</engine:Vector3Field>
<engine:FloatField label="Float Field" name="FloatField">
<Bindings>
<engine:DataBinding property="value" data-source-path="sumOfVector3Properties" binding-mode="ToTarget"/>
</Bindings>
</engine:FloatField>
</engine:VisualElement>
</engine:UXML>
You can use the following methods to manage binding objects:
You can create the bindable properties in the same way as other data sources, which means that you can also use VisualElement types as data sources. The main difference between a VisualElement type and other data sources is that VisualElement types come with built-in versioning. You must use the built-in versioning of a VisualElement type to propagate changes.
To report a change, call the NotifyPropertyChanged method. This method takes a BindingId that identifies the property that changed. BindingId is typically the name of the target property of the UI element.
The following example shows how to report a change for a VisualElement type:
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);
}
}
Follow these tips and best practices to optimize performance:
value property of a Vector3Field, the binding ID must be Vector3Field.valueProperty or value. In a nutshell, the binding ID must match the name or path of the field or property.x, y, and z sub-elements for a Vector3Field. Instead, use a binding to synchronize the value property of the Vector3Field with a Vector3 property of a data source.UI Toolkit doesn’t report changes in element.style and element.resolvedStyle. Therefore, you can use binding instances to target the resolved style of an element but can’t track changes to them.