Unity 6.3
0 онлайн 101 гостей 3 в системе
Вход
UI системы Шаг 179 из 317

События изменения

При изменении значения элемента отправляется сообщение ChangeEvent. Это сообщение обычно отправляется при изменении значения в поле контроля. Например, когда пользователь переключает флажок.

Событие ChangeEvent является типизированным событием и содержит как предыдущее, так и новое значение визуального элемента.

Событие запускается после того, как изменение назначает новое значение визуальному элементу. Вы не можете отменить события изменения, чтобы предотвратить изменение значения визуального элемента.

Базовый класс для ChangeEvent является EventBase class.

В следующей таблице описывается событие изменения и фазы его распространения:

Мероприятие Описание Просыпается Пузырьки вверх Аннулируемые
ChangeEvent Общее событие, отправляемое при изменении значения элемента. Да Да Нет

Уникальные свойства

previousValue: предыдущее значение целевого контроля.

newValue: Новое значение целевого элемента управления.

Список событий

ChangeEvent

ChangeEvent — это событие уведомления, которое позволяет реагировать на изменение значения визуального элемента. Например, когда вы переключаете флажок для выключения музыки в игре, игра должна останавливать всю музыку.

Это событие применяется ко всем элементам управления, реализующим INotifyValueChanged<T>, где <T> является типом ChangeEvent. Это событие также используется внутри объекта для обновления свойств в объектах, связанных с UI через Bindings.

Он запускает даже когда значение контроля устанавливается кодом. Вы можете изменить значение на контроле без запуска ChangeEvent по телефону SetValueWithoutNotify в 2000 году INotifyValueChange<T> interface.

Вы можете зарегистрировать функцию обратного вызова для получения ChangeEvent двумя способами:

  1. Вызов RegisterCallback<>() на визуальном элементе
  2. Вызов RegisterValueChangedCallback() на визуальном элементе, полученном из INotifyValueChange<T>

Регистрация обратного вызова через RegisterCallback работает для всех визуальных элементов независимо от того, хранят ли они внутренние значения. Если вы хотите отслеживать любые изменения в дочерних элементах управления родительского элемента, используйте именно этот метод.

Поскольку ChangeEvent является событием типа, вы должны указать его тип при регистрации события. Приведенный ниже код демонстрирует регистрацию и получение ChangeEvent типа bool.

// 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
}

Цель, распространение и фильтрация

ChangeEvent участвует как в фазе trickle-down, так и в фазе bubble-up. Обратный вызов, зарегистрированный на элементе предка, получает каждый соответствующий ChangeEvent, который происходит от элемента потомка по мере того, как событие поднимается вверх по дереву.

В рамках обратного вызова используйте следующие свойства, чтобы увидеть, как событие достигло обработчика:

Свойство Значение для ChangeEvent
EventBase.target Визуальный элемент, который отправил для изменения (где значение фактически изменилось).
EventBase.currentTarget Визуальный элемент, на котором ваш callback был зарегистрирован.

Если вас интересует только один конкретный элемент управления, сравните evt.target с этим элементом (или с известным дочерним элементом) перед запуском логики. RegisterValueChangedCallback вызывают RegisterCallback для ChangeEvent<T> на этом элементе управления; это не останавливает другие элементы управления от отправки своих собственных ChangeEvent, и обработчик на родительском элементе управления всё равно получает события в виде пузырьков от братьев или вложенных полей, когда тип события совпадает.

Составные элементы управления могут включать несколько внутренних полей. Обновление связанного интерфейса (например, меток или вложенных полей) внутри обработчика изменения значения может вызвать дополнительные ChangeEventс или вложенные Чтобы избежать непреднамеренной работы или обратной связи, фильтруйте с помощью evt.target, предпочтительно SetValueWithoutNotify когда программные обновления не должны уведомлять, и держать побочные эффекты обработчика минимальными.

Как target и currentTarget ведут себя во время отправки, см. в События отправки.

Примеры

Следующие примеры демонстрируют использование ChangeEvent и как установить и получить контрольное значение.

Чтобы просмотреть пример, выполните следующие действия:

  1. В разделе Активы > Сценарии > Редакторсоздайте скрипт C# под названием ChangeEventTestWindow.
  2. Скопируйте примерный код в скрипт C#.
  3. На панели редактора выберите Окно > UI Toolkit > Тестовое окно «Изменение событий»

Пример 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()
    {
        // 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)
    {
        // currentTarget is rootVisualElement; target is the control whose value changed (here, the toggle).
        Debug.Log($"Parent callback: target={evt.target.name}, currentTarget={evt.currentTarget.name}; " +
            $"old value: {evt.previousValue}, new value: {evt.newValue}");
    }

    private void OnTestToggleChanged(ChangeEvent<bool> evt)
    {
        // currentTarget and target are both the toggle when the callback is registered on the toggle.
        Debug.Log($"Toggle callback: target={evt.target.name}, currentTarget={evt.currentTarget.name}; " +
            $"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()
    {
        // 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);
    }
}