Version: 2020.3
捕获事件
命令事件

更改事件

当某个元素值更改时,发送 ChangeEvent 事件。通常在控件的字段值发生更改时发送。例如,当用户切换复选框时。

ChangeEvent 是一个类型化事件,包含视觉元素的前一个值和新值。

该事件在更改行为将新值指定给视觉元素后触发。您不能通过取消更改事件来阻止视觉元素上的值更改。

ChangeEvent 的基类是 EventBase 类。

事件 描述 涓滴 冒泡 可取消
ChangeEvent 当某个元素的值更改时发送的通用事件。

独特的属性

previousValue:目标控件的先前值。

newValue:目标控件的新值。

事件列表

ChangeEvent

ChangeEvent 是一个通知事件,允许您对视觉元素的值变化做出反应。例如,当您在游戏中切换复选框以将音乐静音时,游戏应停止所有音乐。

此事件适用于所有实现 INotifyValueChanged<T>,其中 <T>ChangeEvent 的类型。此事件也内部用于对通过绑定链接到 UI 的对象内属性进行更新。

即使控件的值是由代码设置的,它也会触发。您可以通过调用 INotifyValueChange<T> 接口中的 SetValueWithoutNotify 在不触发 ChangeEvent 的情况下修改控件上的值。

您可以通过两种方式注册回调函数以接收 ChangeEvent

1.在视觉元素上调用 RegisterCallback<>() 2.在派生自 INotifyValueChange<T> 的视觉元素上调用 RegisterValueChangedCallback()

通过 RegisterCallback 注册回调适用于所有视觉元素,无论它们是否存储内部值。如果您想监听父元素的子控件中发生的任何更改,则可以使用此方法。

因为 ChangeEvent 是一个类型化事件,所以在注册事件时必须指定类型。下面的代码演示了注册和接收类型为 boolChangeEvent

// 注册回调
rootVisualElement.RegisterCallback<ChangeEvent<bool>>(OnBoolChangedEvent);
//事件回调
private void OnBoolChangedEvent(ChangeEvent<bool> evt) 
{ 
    // 处理代码
}

保存值的元素(如开关和整数字段)实现了 INotifyValueChange<T> 接口。可以通过调用 RegisterValueChangedCallback 直接在这些元素上注册回调。这是一种更方便的注册回调的方法,因为类型已经内置。您可以通过调用 myElement.UnregisterValueChangedCallback 取消注册事件处理程序。

var newToggle = new Toggle("Test Toggle");
newToggle.RegisterValueChangedCallback(OnTestToggleChanged);
private void OnTestToggleChanged(ChangeEvent<bool> evt)
{ 
    // 处理代码
}

target:发生状态变化的元素。

示例

以下示例演示了 ChangeEvent 的用法以及如何设置和获取控件值。

要查看示例,请执行以下操作:

1.在 Assets > Scripts > Editor 下,创建一个 C# 脚本,名为 ChangeEventTestWindow。 2.将该示例代码复制到 C# 脚本。 3.从编辑器工具栏中,选择 Window > UI Toolkit > Change Events Test Window

示例 1:注册接收更改事件的回调

using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public class ChangeEventTestWindow : EditorWindow
{
    private Toggle m_MyToggle;

    [MenuItem("Window/UI Toolkit/Change Event Test Window")]
    public static void ShowExample()
    {
        ChangeEventTestWindow wnd = GetWindow<ChangeEventTestWindow>();
        wnd.titleContent = new GUIContent("Change Event Test Window");
    }

    public void CreateGUI()
    {
        // 创建一个开关
        m_MyToggle = new Toggle("Test Toggle") { name = "My Toggle" };
        rootVisualElement.Add(m_MyToggle);

        // 在开关上注册回调
        m_MyToggle.RegisterValueChangedCallback(OnTestToggleChanged);

        // 在父级上注册回调
        rootVisualElement.RegisterCallback<ChangeEvent<bool>>(OnBoolChangedEvent);
    }

    private void OnBoolChangedEvent(ChangeEvent<bool> evt)
    {
        Debug.Log($"Toggle changed.Old value: {evt.previousValue}, new value: {evt.newValue}");
    }

    private void OnTestToggleChanged(ChangeEvent<bool> evt)
    {
        Debug.Log($"A bool value changed.Old value: {evt.previousValue}, new value: {evt.newValue}");
    }
}

示例 2:通过代码设置控制值

using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public class ChangeEventTestWindow : EditorWindow
{
    private Toggle m_MyToggle;

    [MenuItem("Window/UI Toolkit/Change Event Test Window")]
    public static void ShowExample()
    {
        GetWindow<ChangeEventTestWindow>().titleContent = new GUIContent("Change Event Test Window");
    }

    public void CreateGUI()
    {
        // 创建开关和注册回调 
        m_MyToggle = new Toggle("Test Toggle") { name = "My Toggle" };
        m_MyToggle.RegisterValueChangedCallback((evt) => { Debug.Log("Change Event received"); });
        rootVisualElement.Add(m_MyToggle);

        // 创建按钮来切换开关的值
        Button button01 = new Button() { text = "Toggle" };
        button01.clicked += () => 
        {
            m_MyToggle.value = !m_MyToggle.value;
        };
        rootVisualElement.Add(button01);

        // 创建按钮以在不触发 ChangeEvent 的情况下切换开关的值
        Button button02 = new Button() { text = "Toggle without notification" };
        button02.clicked += () =>
        {
            m_MyToggle.SetValueWithoutNotify(!m_MyToggle.value);
        };
        rootVisualElement.Add(button02);
    }
}
捕获事件
命令事件