您可以创建自定义绑定类型来扩展运行时绑定系统。要创建自定义绑定类型,请创建一个类并从 CustomBinding
类继承。
CustomBinding
类似于 IBinding
接口,它允许您注册多个绑定实例,而不是单个实例。CustomBinding
是一个可扩展性入口点,仅提供 Update
方法来更新绑定。但是,您可以实现以下方法以在绑定注册、注销以及数据源上下文在元素上发生更改时接收回调
要为绑定类型定义数据源和数据源路径,请实现 IDataSourceProvider
接口。绑定系统使用此接口提供的 dataSource
和 dataSourcePath
属性来确定解析后的数据源和数据源路径。这些属性被称为“本地”,因为它们会覆盖从层次结构中获得的值。重要的是,修改这些“本地”属性不会影响元素本身或其任何后代。
默认情况下,绑定系统会在每一帧更新 CustomBinding
实例。
要定义更新触发器,请使用以下方法
MarkDirty
:将绑定对象设置为 dirty
,以便它在下一个周期内得到更新。updateTrigger
:使用此 enum
属性更改绑定的更新方式。BindingResult
:使用此方法自定义更新过程。 BindingResult
是一个结构体,它告诉您更新是否成功。它包含一个 status
和一个 message
。BindingResult
包含一个 status
和一个 message
。以下是 status
的可能值
您可以使用 BindingResult
方法的 Pending
结果来通知绑定系统,如果绑定对象需要在下一个周期内更新。
本节提供一个示例,演示如何创建自定义绑定类型并在 UI(用户界面) 允许用户与您的应用程序进行交互。Unity 目前支持三种 UI 系统。 更多信息
参见 术语表 Builder、UXML 和 C# 中设置绑定。
以下示例创建了一个自定义绑定类型,它显示当前时间。您可以将其绑定到 Label 的 text
属性,以创建时钟。
using System;
using Unity.Properties;
using UnityEngine.UIElements;
[UxmlObject]
public partial class CurrentTimeBinding : CustomBinding
{
[UxmlAttribute]
public string timeFormat = "HH:mm:ss";
public CurrentTimeBinding()
{
updateTrigger = BindingUpdateTrigger.EveryUpdate;
}
protected override BindingResult Update(in BindingContext context)
{
var timeNow = DateTime.Now.ToString(timeFormat);
var element = context.targetElement;
if (ConverterGroups.TrySetValueGlobal(ref element, context.bindingId, timeNow, out var errorCode))
return new BindingResult(BindingStatus.Success);
// Error handling
var bindingTypename = TypeUtility.GetTypeDisplayName(typeof(CurrentTimeBinding));
var bindingId = $"{TypeUtility.GetTypeDisplayName(element.GetType())}.{context.bindingId}";
return errorCode switch
{
VisitReturnCode.InvalidPath => new BindingResult(BindingStatus.Failure, $"{bindingTypename}: Binding id `{bindingId}` is either invalid or contains a `null` value."),
VisitReturnCode.InvalidCast => new BindingResult(BindingStatus.Failure, $"{bindingTypename}: Invalid conversion from `string` for binding id `{bindingId}`"),
VisitReturnCode.AccessViolation => new BindingResult(BindingStatus.Failure, $"{bindingTypename}: Trying set value for binding id `{bindingId}`, but it is read-only."),
_ => throw new ArgumentOutOfRangeException()
};
}
}
创建自定义绑定类型后,它将显示在 UI Builder 的“添加绑定”窗口中。要在 UI Builder 中设置绑定,请在“添加绑定”窗口中从“类型”列表中选择“CurrentTimeBinding”。
此绑定的 UXML 等效项如下
<ui:Label text="Label">
<Bindings>
<CurrentTimeBinding property="text" />
</Bindings>
</ui:Label>
此绑定的 C# 等效项如下
var label = new Label();
label.SetBinding("text", new CurrentTimeBinding());
遵循以下提示和最佳实践以优化性能
BindingUpdateTrigger.OnSourceChanged
:如果您的绑定类型仅在检测到源中的更改时才需要更新,请将 updateTrigger
设置为 BindingUpdateTrigger.OnSourceChanged
。这可以确保仅在必要时更新绑定类型,从而优化性能。BindingUpdateTrigger.WhenDirty
进行手动更新:如果您手动更新绑定类型并且不需要立即同步,请将 updateTrigger
设置为 BindingUpdateTrigger.WhenDirty
。这允许您手动控制绑定类型更新的时间,从而提供灵活性并控制同步。OnActivated
、OnDeactivated
或 OnDataSourceChanged
回调,而不是 Update
回调。这些回调是在特定生命周期事件触发时触发的,减少了不必要的更新并提高了效率。通过使用适当的回调,您可以优化绑定类型的行为,并确保更新在需要时准确发生。