UI 工具包中的事件类似于 HTML 事件。事件发生时,UI 工具包会将其发送到目标视觉元素以及视觉树中传播路径中的所有元素。
事件处理顺序如下:
在事件沿传播路径移动时,Event.currentTarget 属性更新为当前正在处理事件的元素。在事件回调函数中:
Event.currentTarget 是回调注册的视觉元素。Event.target 是原始事件发生的视觉元素。更多信息,请参阅分发事件。
通过注册事件回调,您可以自定义现有类的单个实例的行为,例如对鼠标点击文本标签做出反应。要注册事件的回调,请使用 RegisterCallback() 方法直接在元素上注册回调。
传播路径上的每个元素(目标除外)对一个事件可以接收两次:
默认情况下,已注册的回调会在目标阶段和冒泡阶段执行。此默认行为可确保父元素在其子元素之后做出反应。
但是,如果您希望父元素在其子元素之前做出反应,请使用 TrickleDown.TrickleDown 选项注册回调:
using UnityEngine;
using UnityEngine.UIElements;
...
VisualElement myElement = new VisualElement();
// Register a callback for the trickle-down phase.
myElement.RegisterCallback<PointerDownEvent>(MyCallback, TrickleDown.TrickleDown);
...
此代码将通知分发程序在目标阶段和涓滴阶段执行回调。
要将自定义行为添加到特定的视觉元素,需要在该元素上注册事件回调,如下所示:
// Register a callback on a pointer down event
myElement.RegisterCallback<PointerDownEvent>(MyCallback);
回调函数的签名如下所示:
void MyCallback(PointerDownEvent evt) { /* ... */ }
对于其子元素处理事件的元素,要注册回调,需使用 Q() 方法查找子元素并在其上注册回调。
以下示例在滑动条的拖动容器元素上注册了回调,以处理滑动条的指针向上事件。在这种情况下,必须在拖动容器元素(而不是滑动条本身)上注册回调,因为拖动容器在指针向下事件期间捕获指针,这使得它成为下一个指针向上事件的唯一接收者。
var dragContainer = slider.Q("unity-drag-container");
dragContainer.RegisterCallback<PointerUpEvent> ( evt => Debug.Log("PointerUpEvent"));
注意:您可以为一个事件注册多个回调。但同一事件的同一回调函数在传播阶段只能注册一次。
要从 VisualElement 中删除回调,请调用 myElement.UnregisterCallback() 方法。
有关如何从 MonoBehaviour 访问视觉元素的信息,请参阅开始使用运行时 UI。
您可以将自定义数据与回调一起发送到事件。如果要附加自定义数据,必须通过扩展该调用的方式来注册回调。
以下示例为 PointerDownEvent 注册一个回调并将自定义数据发送到回调函数:
// Send user data along to the callback
myElement.RegisterCallback<PointerDownEvent, MyType>(MyCallbackWithData, myData);
回调函数的签名如下所示:
void MyCallbackWithData(PointerDownEvent evt, MyType data) { /* ... */ }
UI 控件使用 value 属性来保存其内部状态的数据。例如:
Toggle 包含布尔值,该值在打开或关闭 Toggle 时会更改。IntegerField 包含整数,其中包含字段的值。通过以下步骤可以获取字段的值:
直接从控件获取值:int val = myIntegerField.value;。
监听控件发送的 ChangeEvent,并在发生更改时及时处理。您必须按如下所示将回调注册到事件:
//RegisterValueChangedCallback is a shortcut for RegisterCallback<ChangeEvent>.
//It constrains the right type of T for any VisualElement that implements an
//INotifyValueChange interface.
myIntegerField.RegisterValueChangedCallback(OnIntegerFieldChange);
回调函数的签名如下所示:
void OnIntegerFieldChange(ChangeEvent<int> evt) { /* ... */ }
通过以下步骤可以更改控件的值:
value 变量:myControl.value = myNewValue;。这会触发新的 ChangeEvent。myControl.SetValueWithoutNotify(myNewValue);。这不会触发新的 ChangeEvent。更多相关信息,请参阅更改事件