Opps yes it is a string - an important detail.
[TypeConverter(typeof(OccurrenceStatusEnumConverter))]
public enum OccurrenceStatus
{
[LocalizedDescription(typeof(Labels), "OccurrenceStatus_AllActive")]
All_Active,
[LocalizedDescription(typeof(Labels), "OccurrenceStatus_Open")]
Open,
[LocalizedDescription(typeof(Labels), "OccurrenceStatus_InProgress")]
In_Progress,
[LocalizedDescription(typeof(Labels), "OccurrenceStatus_Closed")]
Closed,
[LocalizedDescription(typeof(Labels), "OccurrenceStatus_Deleted")]
Deleted
}
The string in the DB is one of these values:
null
Closed
Deleted
In Progress
Open
(All_Active isn't in DB)
FTR
public class OccurrenceStatusEnumConverter : EnumerationConverter<OccurrenceStatus>
{
public override string ConvertEnumToString(OccurrenceStatus value)
{
return Convert.ToString(value).Replace(GeneralHelper.EnumSpaceSubstitute, ' ');
}
}
/// <summary>
/// Converter with as core type System.Enum, for mapping a field with a .NET type System.Enum onto a numeric or string database field
/// </summary>
/// <remarks>Unfortunately a subclass is need for every enum as the LLBL designer doesn't support generic type converters</remarks>
/// <see cref="http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=7355"/>
/// <see cref="http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=7945"/>
/// <see cref="http://www.llblgen.com/documentation/2.6/hh_start.htm"/>
/// <seealso cref="System.ComponentModel.EnumConverter"/>
/// <example>Usage public class MyEnumConverter : EnumerationConverter<!--MyEnum-->{}</example>
/// <typeparam name="T"></typeparam>
[Description("Converter with as core type System.Enum, for mapping a field with a .NET type System.Enum onto a numeric or string database field")]
public abstract class EnumerationConverter<T> : TypeConverter where T : struct
{
public static readonly IList<TypeCode> ValidTypeCodes = new[]
{
TypeCode.SByte, TypeCode.Byte, TypeCode.UInt16, TypeCode.Int16, TypeCode.UInt32,
TypeCode.Int32, TypeCode.UInt64, TypeCode.Int64, TypeCode.Decimal, TypeCode.String
};
/// <summary>
/// Used for converting any spaces in the DB version of an enum name to a substitute in the CLR enum name.
/// </summary>
/// <example>In_Progress -to- "In Progress"</example>
/// <remarks>This can be changed by setting it in a constructor</remarks>
internal static char SpaceSubstitute = GeneralHelper.EnumSpaceSubstitute;
/// <summary>
/// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
/// <param name="sourceType">A <see cref="T:System.Type"/> that represents the type you want to convert from.</param>
/// <returns>
/// true if this converter can perform the conversion; otherwise, false.
/// </returns>
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == null)
throw new ArgumentNullException(nameof(sourceType));
return ValidTypeCodes.Contains(Type.GetTypeCode(sourceType));
}
/// <summary>
/// Returns whether this converter can convert the object to the specified type, using the specified context.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
/// <param name="destinationType">A <see cref="T:System.Type"/> that represents the type you want to convert to.</param>
/// <returns>
/// true if this converter can perform the conversion; otherwise, false.
/// </returns>
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == null)
throw new ArgumentNullException(nameof(destinationType));
return ValidTypeCodes.Contains(Type.GetTypeCode(destinationType));
}
/// <summary>
/// Converts the given object to the type of this converter, using the specified context and culture information.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
/// <param name="culture">The <see cref="T:System.Globalization.CultureInfo"/> to use as the current culture.</param>
/// <param name="value">The <see cref="T:System.Object"/> to convert.</param>
/// <returns>
/// An <see cref="T:System.Object"/> that represents the converted value.
/// </returns>
/// <exception cref="T:System.NotSupportedException">
/// The conversion cannot be performed.
/// </exception>
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value == null)
return null;
var valueTypeCode = Type.GetTypeCode(value.GetType());
if (valueTypeCode == TypeCode.DBNull)
return null;
var type = typeof (T);
if (valueTypeCode == TypeCode.String)
{
var s = (string) value;
if (string.IsNullOrEmpty(s))
throw new ArgumentNullException(nameof(value));
if (s == "undefined" && !Enum.IsDefined(type, s)) //"undefined" =~ javascript null
return null;
return ConvertFromStringToEnum(s);
}
if (valueTypeCode == TypeCode.Decimal)
value = Convert.ToUInt64(value);
if (ValidTypeCodes.Contains(valueTypeCode))
return Enum.ToObject(MetaDataHelper.GetUnderlyingTypeIfNullable(type), value);
throw new NotSupportedException(String.Format("Conversion from a value of type '{0}' to '{1}' isn't supported.", value.GetType(), type.Name));
}
/// <summary>
/// Converts a string to the enum.
/// </summary>
/// <param name="value">The string value.</param>
/// <returns>The enum</returns>
public virtual T ConvertFromStringToEnum(string value)
{
return (value).ToEnum<T>(SpaceSubstitute);
}
/// <summary>
/// Converts the given value object to the specified type, using the specified context and culture information.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
/// <param name="culture">A <see cref="T:System.Globalization.CultureInfo"/>. If null is passed, the current culture is assumed.</param>
/// <param name="value">The <see cref="T:System.Object"/> to convert.</param>
/// <param name="destinationType">The <see cref="T:System.Type"/> to convert the <paramref name="value"/> parameter to.</param>
/// <returns>
/// An <see cref="T:System.Object"/> that represents the converted value.
/// </returns>
/// <exception cref="T:System.ArgumentNullException">
/// The <paramref name="destinationType"/> parameter is null.
/// </exception>
/// <exception cref="T:System.NotSupportedException">
/// The conversion cannot be performed.
/// </exception>
public override object ConvertTo(ITypeDescriptorContext context,
CultureInfo culture,
object value,
Type destinationType)
{
if (destinationType == null)
throw new ArgumentNullException(nameof(destinationType));
if (value == null)
return null;
//Debug.Assert(value is T);
return destinationType == typeof (string)
? ConvertEnumToString((T) value)
: culture == null ? Convert.ChangeType(value, destinationType) : Convert.ChangeType(value, destinationType, culture);
}
/// <summary>
/// Converts the enum to a string.
/// </summary>
/// <param name="value">The enum value.</param>
/// <returns></returns>
public virtual string ConvertEnumToString(T value)
{
return (value as Enum).EnumToString(SpaceSubstitute, false);
}
///<summary>
/// If the string contains any EnumSpaceSubstitute characters then they are replaced with a space character
///</summary>
///<param name="value">string version of an enum</param>
///<returns>string version of an enum with spaces in it as required</returns>
public static string ReplaceSubstituteWithSpace(string value)
{
return value.Replace(SpaceSubstitute, ' ');
}
/// <summary>
/// Creates an instance of the type that this <see cref="T:System.ComponentModel.TypeConverter"/> is associated with, using the specified context, given a set of property values for the object.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
/// <param name="propertyValues">An <see cref="T:System.Collections.IDictionary"/> of new property values.</param>
/// <returns>
/// An <see cref="T:System.Object"/> representing the given <see cref="T:System.Collections.IDictionary"/>, or null if the object cannot be created. This method always returns null.
/// </returns>
public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
{
return default(T);
}
}