Version: 6000.3
语言: 中文
使用纵器捕获指针
元素的焦点顺序

处理事件回调和值更改

UI Toolkit 中的事件类似于 HTML 事件。当事件发生时,UI Toolkit 会将其发送到目标视觉元素实例化或派生自 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.

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

其他资源

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