版本:Unity 6 (6000.0)
语言:English
使用操纵器捕获指针
元素的焦点顺序

处理事件回调和值更改

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

事件处理顺序如下

  1. 从根元素到事件目标,在元素上执行事件回调。这是调度过程的自上而下阶段。
  2. 从事件目标到根,在元素上执行事件回调。这是调度过程的冒泡阶段。

当事件沿着传播路径移动时,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

有关更多信息,请参阅更改事件

其他资源

使用操纵器捕获指针
元素的焦点顺序