UI 工具包中的事件类似于HTML 事件。当事件发生时,UI 工具包会将其发送到目标视觉元素视觉树的一个节点,它实例化或派生自 C# VisualElement
类。您可以设置外观样式,定义行为,并将其作为 UI 的一部分显示在屏幕上。 更多信息
参见词汇表以及视觉树由轻量级节点组成的对象图,包含窗口或面板中的所有元素。它定义了您使用 UI 工具包构建的每个 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
。有关更多信息,请参阅更改事件