Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved Is binding supposed to work?

Discussion in 'UI Toolkit' started by JasonC_, Jun 6, 2021.

  1. JasonC_

    JasonC_

    Joined:
    Oct 27, 2019
    Posts:
    66
    https://docs.unity3d.com/Packages/com.unity.ui@1.0/api/UnityEngine.UIElements.Toggle.html says:

    > To bind the Toggle's state to a boolean variable, set ... the C# bindingPath to the variable name.

    So I did that:

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3. using UnityEngine.UIElements;
    4.  
    5. public class SomeWindow : EditorWindow {
    6.  
    7.     [MenuItem("Window/Some Window")]
    8.     public static void ShowExample() => GetWindow<SomeWindow>();
    9.  
    10.     public bool SomeValue = true;
    11.  
    12.     public void CreateGUI () => rootVisualElement.Add(new Toggle("some value") {
    13.         bindingPath = "SomeValue"
    14.     });
    15.  
    16.     void Update () => Debug.Log(SomeValue);
    17.  
    18. }
    And it does nothing; just shows an (initially unchecked) box and prints "True" until the window is closed.

    What am I missing.... ? The binding system is fully implemented, right?

    2020.3.10f1
     
    Last edited: Jun 6, 2021
  2. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,260
    The binding system is not fully implemented right now, it doesn't work at runtime or with anything other than a SerializedObject.
     
    JasonC_ likes this.
  3. JasonC_

    JasonC_

    Joined:
    Oct 27, 2019
    Posts:
    66
    Thanks. Disappointing, but at least I can stop scratching my head.

    So for now the only (non-IMGUI) option is to sync the value with the control manually? E.g.:

    Code (CSharp):
    1. using System.Diagnostics;
    2. using UnityEditor;
    3. using UnityEngine.UIElements;
    4. using Debug = UnityEngine.Debug;
    5.  
    6. public class SomeWindow : EditorWindow {
    7.  
    8.     [MenuItem("Window/Some Window")]
    9.     public static void ShowExample() => GetWindow<SomeWindow>();
    10.  
    11.     // ----- until binding api is complete: -----
    12.     // goal: toggle change reflected in property + property change reflected in toggle.
    13.  
    14.     bool someValue = true;
    15.     public bool SomeValue {
    16.         get => someValue;
    17.         set { toggle?.SetValueWithoutNotify(value); OnSomeValueChanged(someValue = value); }
    18.     }
    19.  
    20.     Toggle toggle;
    21.     void CreateGUI () {
    22.         rootVisualElement.Add(toggle = new Toggle("some value") { value = SomeValue });
    23.         toggle.RegisterValueChangedCallback((e) => SomeValue = e.newValue);
    24.     }
    25.  
    26.     // ----- end toggle setup, test code follows -----
    27.  
    28.     bool? prevValueForAssert;
    29.     void OnSomeValueChanged (bool newValue) {
    30.         Debug.Assert(SomeValue == newValue && someValue == newValue && newValue != prevValueForAssert);
    31.         prevValueForAssert = newValue;
    32.         Debug.Log($"some value: {someValue}");
    33.     }
    34.  
    35.     readonly Stopwatch timer = Stopwatch.StartNew();
    36.     void Update () {
    37.         for (; timer.ElapsedMilliseconds >= 2000; timer.Restart())
    38.             SomeValue = !SomeValue; // should not cause toggle cb feedback
    39.     }
    40.  
    41. }
    42.  
     
    Last edited: Jun 7, 2021
  4. martinpa_unity

    martinpa_unity

    Unity Technologies

    Joined:
    Oct 18, 2017
    Posts:
    471
    In your original snippet, what you are missing is an actual object to bind against. As @Chris-Trueman said, the current binding system only works with SerializedObject/SerializedProperty.

    To make your snippet work, you would need to add this line in the CreateGUI method:
    Code (CSharp):
    1. rootVisualElement.Bind(new SerializedObject(this));
     
    JasonC_ and Chris-Trueman like this.