How to repaint from a Property Drawer?

From custom editors when you change something that you know affects the layout / content of the GUI you can force a redraw using Repaint()

How would you do this from a Property Drawer? It seems like there isn’t a way to reference the Editor that contains the Property Drawer to call the Repaint.

Immediate Repaint of the current inspector without reflection or anything funny, works and tested:

public static void RepaintInspector(SerializedObject BaseObject)
    {
        foreach (var item in ActiveEditorTracker.sharedTracker.activeEditors)
            if (item.serializedObject == BaseObject)
            { item.Repaint(); return; }
    }

how does it work?
It utilizes an undocumented unity class called ‘ActiveEditorTracker’, Very USEFUL class that shows you all the Active editors in the inspector. to find the Actual editor the property drawer is a part of we iterate until we find the editor with the SerializedObject the same as our property, we then repaint it.

This class is like magic, I have been doing editor improvements for the last month and a half and it has been a godsend. (you can use it to draw OnSceneGUI from a property drawer as well with some tricks) Would love to see it actually documented.

I know this is an extremely old question but if someone comes across this and is looking for the real solution this is it.

EditorUtility.SetDirty( property.serializedObject.targetObject ); // Repaint

Ok, I know I’m late to the party but this worked for me and it might help others:

I check if the object has changed and then inside my check I apply those changed properties and update. I’ve not included the dirty checking as that’s likely to change a lot between implementations anyway.

serializedObject.ApplyModifiedProperties();
serializedObject.Update();

All the Repaint method in an editor actually does, is calling a static method in the InspectorWindow class. Unfortunately this class is an internal class. So you basically have two options:

  • Create a temporary instance of an Editor to get your hands on the Repaint method and use DestroyImmediate right after it.
  • Use reflection to call the static method manually.

I would go for the second solution:

public static class InspectorHelpers
{
    private static System.Reflection.MethodInfo m_RepaintInspectors = null;
    public static void RepaintAllInspectors()
    {
        if (m_RepaintInspectors == null)
        {
            var inspWin = typeof(EditorApplication).Assembly.GetType("UnityEditor.InspectorWindow");
            m_RepaintInspectors = inspWin.GetMethod("RepaintAllInspectors", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic );
        }
        m_RepaintInspectors.Invoke(null, null);
    }
}

Haven’t tested the class but it should work this way :wink:

HandleUtility.Repaint worked for me and it has been around since forever.

There may be a way to reference the Editor in question, but I haven’t found one. What I have done instead is to ask the object that the PropertyDrawer represents, whether it wants to be repainted from your CustomEditor class. I suspect there is a more elegant way, but this is what works for me.

	[CanEditMultipleObjects]
	[CustomEditor(typeof(YourClass)) ]
	public class YourCustomEditor : Editor
	{
			public override void OnInspectorGUI ()
			{
					serializedObject.Update();
					base.OnInspectorGUI ();
					serializedObject.ApplyModifiedProperties();
					YourClass lite = (YourClass) target;
					if ( lite.ShouldRepaint() )
					{
						Repaint ();
					}
					
			}
	}

Oddly, none of these solutions worked for me. I stumbled upon this, and it works for my limited tests so far…

property.serializedObject.Update();  //not sure if required for redraw, but MY code needs it
EditorApplication.update.Invoke();

My solution (Japanese only page):

In brief:

  1. Add some repainting action (like @rnhfjkui does) to EditorApplication.update in OnGUI()
  2. Add an action removing the repainting action to Selection.selectionChanged in OnGUI()
  3. Remove the removing action in itself
  4. Get along with some unbelievable errors