[Unity6] Order of execution of INotifyValueChanged callback and bound property updates

Hello.
I am experimenting with UIToolKit runtime data binding.
Is it a specification that the callback added by RegisterValueChangedCallback is executed before updating the Property of the DataSource that is bound?

For example, suppose the following program is written.

public class TestViewModel
{
    private float _sliderValue;

    [CreateProperty]
    public float SliderValue
    {
        get => _sliderValue;
        set
        {
            _sliderValue = value;
            UnityEngine.Debug.Log($"[TestViewModel] SliderValue updated: {value}");
        }
    }
}

[RequireComponent(typeof(UIDocument))]
public class Testing : MonoBehaviour
{
    private VisualElement _element;
    private readonly TestViewModel _testViewModel = new();

    private void Awake()
    {
        _element = GetComponent<UIDocument>().rootVisualElement;
        var slider = _element.Q<Slider>("Slider");
        slider.RegisterValueChangedCallback(evt => OnSliderValueChanged(evt.newValue));

        slider.SetBinding(
            bindingId: nameof(Slider.value),
            binding: new DataBinding()
            {
                dataSource = _testViewModel,
                dataSourcePath = PropertyPath.FromName(nameof(TestViewModel.SliderValue)),
                dataSourceType = typeof(float),
            }
        );
    }

    private void OnSliderValueChanged(float newValue)
    {
        UnityEngine.Debug.Log($"[OnSliderValueChanged] currentViewModelSliderValue: {_testViewModel.SliderValue}");
        UnityEngine.Debug.Log($"[OnSliderValueChanged] newValue: {newValue}");
    }
}

Then the logs show the following.

[OnSliderValueChanged] currentViewModelSliderValue: 40.5
[OnSliderValueChanged] newValue: 71.1
[TestViewModel] SliderValue updated: 71.1

We can confirm that the value of TestingViewModel.SliderValue has not yet been updated at the execution timing of OnSliderValueChanged.

If it is a spec, is there a way to work around this and update the property value before the callback is executed…?

Hi @hinahoshi,

The data source will be updated after the control’s value has changed. This process is asynchronous, because you might change a control’s value outside of the binding update loop. This is by-design and there is no work around to update the data source before the control’s value has changed.

During the bindings update, we will go through unprocessed (queued up) changes detected from a control, then run the binding update (i.e. bindings from data source to UI), then go through queued up changes detected during the binding update.

Hope this helps!

I see. Thank you very much.
By the way, is there any documentation that describes the flow of updating that data?

I think it would be helpful for many developers to have a document like ExecutionOrder