Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Repaint not causing EditorWindow to repaint

Discussion in 'UIElements' started by Fedora_Dev, Jul 8, 2019.

  1. Fedora_Dev

    Fedora_Dev

    Joined:
    Oct 28, 2016
    Posts:
    16
    Hello all,

    I've been working on an Editor Window for a while now while learning UIElements. It's to my understanding that calling `Repaint()` should cause the window to redraw everything, however it appears that it isn't doing so. I have my OnEnable code below. Notice at line #21 I create a button that removes an element and then calls `Repaint()`. When I click the button, the element is removed, however the Window doesn't update with the information. I have to close the Editor Window entirely and reopen it for the update to reflect properly.

    Code (CSharp):
    1. if (quest == null)
    2.             quest = Selection.activeObject as Quest;
    3.  
    4.         VisualElement root = rootVisualElement;
    5.         SerializedObject questObject = new SerializedObject(quest);
    6.  
    7.         TextField descriptionField = new TextField() { label = "Description", multiline = true };
    8.  
    9.         descriptionField.BindProperty(questObject.FindProperty("description"));
    10.  
    11.         root.Add(descriptionField);
    12.  
    13.         Label rewardsLabel = new Label("Rewards");
    14.  
    15.         root.Add(rewardsLabel);
    16.  
    17.         for (int i = 0; i < quest.rewards.Count; i++)
    18.         {
    19.             int index = i;
    20.             RewardFlag flagReward = quest.rewards[i] as RewardFlag;
    21.             Button removeButton = new Button(() => { quest.rewards.RemoveAt(index); Repaint(); });
    22.             removeButton.text = "X";
    23.  
    24.             if (flagReward != null)
    25.             {
    26.                 SerializedObject flagRewardObject = new SerializedObject(flagReward);
    27.                 ObjectField flagField = new ObjectField("Flag");
    28.                 flagField.objectType = typeof(Flag);
    29.                 flagField.BindProperty(flagRewardObject.FindProperty("flag"));
    30.                 flagField.Add(removeButton);
    31.                 flagField.style.flexDirection = FlexDirection.Row;
    32.                 root.Add(flagField);
    33.             }
    34.  
    35.             RewardItem itemReward = quest.rewards[i] as RewardItem;
    36.             if (itemReward != null)
    37.             {
    38.                 SerializedObject itemRewardObject = new SerializedObject(itemReward);
    39.                 InventoryItemEditor inventoryItemEditor = new InventoryItemEditor();
    40.  
    41.                 VisualElement itemElement = inventoryItemEditor.CreatePropertyGUI(itemRewardObject.FindProperty("item"));
    42.                 itemElement.Add(removeButton);
    43.  
    44.                 root.Add(itemElement);
    45.             }
    46.         }
     
  2. AlexandreT-unity

    AlexandreT-unity

    Unity Technologies

    Joined:
    Feb 1, 2018
    Posts:
    24
    You should not have to call Repaint. Are you sure that quest.rewards is a visual element that is in the current visual tree? This works on my end (2019.3.0a8):

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine.UIElements;
    3.  
    4. public class Test : EditorWindow
    5. {
    6.     [MenuItem("Test/Open Window")]
    7.     public static void OpenTestWindow()
    8.     {
    9.         var window = GetWindow<Test>();
    10.         window.Show();
    11.     }
    12.  
    13.     void OnEnable()
    14.     {
    15.         rootVisualElement.Add(new Button(() => {rootVisualElement.RemoveAt(0);}) { text = "Test" });
    16.     }
    17. }
    18.  
    As you remove elements, the indices change, which may cause your lambdas to attempt to remove an element that's not there anymore.
     
    Last edited: Jul 11, 2019
    Fedora_Dev likes this.
  3. Fedora_Dev

    Fedora_Dev

    Joined:
    Oct 28, 2016
    Posts:
    16
    Ah, ok. I guess my mindset is still stuck in Immediate UI. I've updated my code to just remove the element after the array element is removed and that works, of course. Thanks for pointing me in the right direction.