当某个元素值更改时,发送 ChangeEvent 事件。这通常在控件的字段值发生更改时发送。例如,当用户切换复选框时。
ChangeEvent 是一个类型化事件,包含视觉元素的前一个值和新值。
该事件会在更改行为将新值指定给视觉元素后触发。您不能通过取消更改事件来阻止视觉元素的值发生更改。
ChangeEvent 的基类是 EventBase 类。
| 事件 | 描述 | 涓滴 | 冒泡 | 可取消 |
|---|---|---|---|---|
| ChangeEvent | 当某个元素的值更改时发送的通用事件。 | ✔ | ✔ |
previousValue:目标控件的前一个值。
newValue:目标控件的新值。
ChangeEvent 是一个通知事件,允许您对视觉元素的值变化做出反应。例如,当您在游戏中切换复选框以将音乐静音时,游戏应停止所有音乐。
此事件适用于所有实现 INotifyValueChanged<T> 的控件,其中 <T> 是 ChangeEvent 的类型。此事件在内部也用于更新通过绑定链接到 UI 的对象的属性。
即使控件的值是由代码设置的,也会触发。可以通过调用 INotifyValueChange<T> 接口中的 SetValueWithoutNotify 来修改控件的值,而不会触发 ChangeEvent。
您可以通过两种方式注册回调函数以接收 ChangeEvent:
RegisterCallback<>()
INotifyValueChange<T> 的视觉元素调用 RegisterValueChangedCallback()
通过 RegisterCallback 注册回调适用于所有视觉元素,无论是否存储内部值。如果您想监听父元素的子控件中发生的任何更改,可以用此方法。
因为 ChangeEvent 是一个类型化事件,所以在注册事件时必须指定类型。下面的代码演示了注册和接收类型 bool 的 ChangeEvent。
// Registering the callback
rootVisualElement.RegisterCallback<ChangeEvent<bool>>(OnBoolChangedEvent);
// Event callback
private void OnBoolChangedEvent(ChangeEvent<bool> evt)
{
// Handling code
}
保存值的元素(如开关和整数字段)实现了 INotifyValueChange<T> 接口。可以通过调用 RegisterValueChangedCallback 直接在这些元素上注册回调。这是一种更方便的注册回调的方法,其类型已经内置。您可以通过调用 myElement.UnregisterValueChangedCallback 再次取消注册事件处理程序。
var newToggle = new Toggle("Test Toggle");
newToggle.RegisterValueChangedCallback(OnTestToggleChanged);
private void OnTestToggleChanged(ChangeEvent<bool> evt)
{
// Handling code
}
target:发生状态变化的元素。
以下示例演示了 ChangeEvent 的用法以及如何设置和获取控件值。
要查看示例,请执行以下操作:
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()
{
// Create a toggle
m_MyToggle = new Toggle("Test Toggle") { name = "My Toggle" };
rootVisualElement.Add(m_MyToggle);
// Register a callback on the toggle
m_MyToggle.RegisterValueChangedCallback(OnTestToggleChanged);
// Register a callback on the parent
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}");
}
}
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()
{
// Create a toggle and register callback
m_MyToggle = new Toggle("Test Toggle") { name = "My Toggle" };
m_MyToggle.RegisterValueChangedCallback((evt) => { Debug.Log("Change Event received"); });
rootVisualElement.Add(m_MyToggle);
// Create button to toggle the toggle's value
Button button01 = new Button() { text = "Toggle" };
button01.clicked += () =>
{
m_MyToggle.value = !m_MyToggle.value;
};
rootVisualElement.Add(button01);
// Create button to toggle the toggle's value without triggering a ChangeEvent
Button button02 = new Button() { text = "Toggle without notification" };
button02.clicked += () =>
{
m_MyToggle.SetValueWithoutNotify(!m_MyToggle.value);
};
rootVisualElement.Add(button02);
}
}