public static VisualElement CreateAsStringPopupField <TEnum>(SerializedProperty property, Action <TEnum> onValueChanged = null)
            where TEnum : struct, Enum
        {
            Assert.AreEqual(property.propertyType, SerializedPropertyType.Enum);
#if UNITY_2019_3_OR_NEWER
            var enumField = new UnityEditor.UIElements.EnumField
            {
                bindingPath = property.propertyPath
            };
            enumField.RegisterValueChangedCallback(e =>
            {
                if (onValueChanged != null && e.newValue is TEnum newValue)
                {
                    onValueChanged.Invoke(newValue);
                }
            });
            enumField.Bind(property.serializedObject);
            return(enumField);
#else
            // HACK: `Field type UnityEditor.UIElements.EnumField is not compatible with Enum property "myEnum"` in 2019.2
            // ref: https://forum.unity.com/threads/cant-create-bindings-for-an-enum-not-compatible.728111/#post-4873661
            var enumField = new PopupField <string>
            {
                bindingPath = property.propertyPath
            };
            // HACK: `NullReferenceException: Object reference not set to an instance of an object` in 2019.2
            enumField.RegisterValueChangedCallback(_ =>
            {
                onValueChanged?.Invoke((TEnum)(object)enumField.index);
            });
            return(enumField);
#endif
        }