public
Last active

SelectListItem Extension Methods for DropDowns in MVC, Updated comments for better intellisense

  • Download Gist
ExtensionMethods.cs
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
public static class SelectListExtensionMethods
{
//// simple Enum for demonstration in the examples
//enum Colors {
// Red = 1,
// Green = 2,
// Blue = 3
//}
 
//// Simple Class for demonstration in the examples
//class Person {
// public int PersonId { get; set; }
// public string Name { get; set; }
//}
//
//List<Person> people = new List<Person>();
//people.Add(new Person() {PersonId = 1234, Name= "John Doe"});
//people.Add(new Person() {PersonId = 2345, Name= "Jane Doe"});
//people.Add(new Person() {PersonId = 3456, Name= "Bobby"});
 
//// I have some extension methods that use Guids because of a project I work with that uses primarily Guids for it's primary keys.
//// Simple Class for demonstration in the examples with Guids
//class Job {
// public Guid JobId { get; set; }
// public string Name { get; set; }
//}
//
//List<Job> jobs = new List<Job>();
//jobs.Add(new Job() {JobId = Guid.Parse("11111111-1111-1111-1111-111111111111"), Name= "Janitor"});
//jobs.Add(new Job() {JobId = Guid.Parse("22222222-2222-2222-2222-222222222222"), Name= "Salesman"});
//jobs.Add(new Job() {JobId = Guid.Parse("33333333-3333-3333-3333-333333333333"), Name= "Manager"});
 
/// <summary>
/// The SelectListItem to use by default as the placeholder for any select lists generated by these extension methods.
/// </summary>
public static readonly SelectListItem DefaultEmptySelectListItem = new SelectListItem() { Text = "-- Pick One --", Value = "" };
 
#region String Keys
/// <summary>
/// Returns a collection of SelectListItem for each of the items in the collection passed in.
/// </summary>
/// <example>
/// people.ToSelectList(x => x.PersonId, x => x.Name);
/// </example>
/// <param name="key">The property to use as the value attribute of each list item.</param>
/// <param name="text">The property to use as the text attribute of each list item.</param>
public static IList<SelectListItem> ToSelectList<TType, TKey>(this IEnumerable<TType> enumerable, Func<TType, TKey> key, Func<TType, string> text) where TType : class
{
return ToSelectList(enumerable, key, text, null, true);
}
 
/// <summary>
/// Returns a collection of SelectListItem for each of the items in the collection passed in, with a specific list item selected and optionally an empty list item.
/// </summary>
/// <example>
/// <code>
/// people.ToSelectList(x => x.PersonId, x => x.Name, "2345");
/// // or
/// people.ToSelectList(x => x.PersonId, x => x.Name, "2345", false); if you don't want the empty list item
/// </code>
/// </example>
/// <param name="key">The property to use as the value attribute of each list item.</param>
/// <param name="text">The property to use as the text attribute of each list item.</param>
/// <param name="currentKey">The String value of the list item that should be selected by default.</param>
/// <param name="includeEmptyListItem">Whether or not a default list item should be the first list item before those from the collection.</param>
public static IList<SelectListItem> ToSelectList<TType, TKey>(this IEnumerable<TType> enumerable, Func<TType, TKey> key, Func<TType, string> text, TKey currentKey, bool includeEmptyListItem = true) where TType : class
{
return ToSelectList(enumerable, key, text, currentKey, includeEmptyListItem ? DefaultEmptySelectListItem : null);
}
 
/// <summary>
/// Returns a collection of SelectListItem for each of the items in the collection passed in, with a specific list item selected and a custom empty list item.
/// </summary>
/// <example>
/// <code>
/// people.ToSelectList(x => x.PersonId, x => x.Name, "2345", new SelectListItem() {Text = "-- Pick One --", Value = ""});
/// </code>
/// </example>
/// <param name="key">The property to use as the value attribute of each list item.</param>
/// <param name="text">The property to use as the text attribute of each list item.</param>
/// <param name="currentKey">The String value of the list item that should be selected by default.</param>
/// <param name="emptyListItem">The list item to use as the first list item before those from the collection.</param>
public static IList<SelectListItem> ToSelectList<TType, TKey>(this IEnumerable<TType> enumerable, Func<TType, TKey> key, Func<TType, string> text, TKey currentKey, SelectListItem emptyListItem) where TType : class
{
return ToSelectList(enumerable, key, text, new TKey[] { currentKey }, emptyListItem);
}
 
public static IList<SelectListItem> ToSelectList<TType, TKey>(this IEnumerable<TType> enumerable, Func<TType, TKey> key, Func<TType, string> text, IEnumerable<TKey> currentKeys, bool includeEmptyListItem = true) where TType : class
{
return ToSelectList(enumerable, key, text, currentKeys, includeEmptyListItem ? DefaultEmptySelectListItem : null);
}
 
public static IList<SelectListItem> ToSelectList<TType, TKey>(this IEnumerable<TType> enumerable, Func<TType, TKey> key, Func<TType, string> text, IEnumerable<TKey> currentKeys, SelectListItem emptyListItem) where TType : class
{
var selectList = new List<SelectListItem>();
if (enumerable != null)
selectList = enumerable.Select(x => new SelectListItem() { Value = key.Invoke(x).ToString(), Text = text.Invoke(x), Selected = (currentKeys != null && currentKeys.Contains(key.Invoke(x))) }).ToList();
if (emptyListItem != null)
selectList.Insert(0, emptyListItem);
return selectList;
}
#endregion
 
 
 
#region Enumerable Enums
// The following three methods are only present in case you wish to control how the list if Enum's is built, useful if you need to omit some due for security reasons.
// Check out http://www.kodefuguru.com/post/2011/09/21/Empowering-Enums.aspx for a good example of how to do this yourself
public static IList<SelectListItem> ToSelectList<TEnum>(this IEnumerable<TEnum> enumerable, TEnum? currentKey, bool includeEmptyListItem = true) where TEnum : struct
{
return ToSelectList(enumerable, currentKey, includeEmptyListItem ? DefaultEmptySelectListItem : null);
}
public static IList<SelectListItem> ToSelectList<TEnum>(this IEnumerable<TEnum> enumerable, int currentKey, bool includeEmptyListItem = true) where TEnum : struct
{
TEnum enumCurrentKey = (TEnum)Enum.ToObject(typeof(TEnum), currentKey);
return ToSelectList(enumerable, enumCurrentKey, includeEmptyListItem ? DefaultEmptySelectListItem : null);
}
 
/// <summary>
/// Returns a collection of SelectListItem from a provided collection of Enum. Typically you would do this when you are starting with nothing and just have the Enum you want to use.
/// </summary>
/// <example>
/// <code>
/// IEnumerable&lt;EnumName&gt; myEnums = Intellitive.ExtensionMethods.AsEnumerable&lt;EnumName&gt;();
/// myEnums.ToSelectList(currentKey, new SelectListItem() {Text = "-- Pick One --", Value = ""});
/// </code>
/// </example>
public static IList<SelectListItem> ToSelectList<TEnum>(this IEnumerable<TEnum> enumerable, TEnum? currentKey, SelectListItem emptyListItem) where TEnum : struct
{
var selectList = new List<SelectListItem>();
if (enumerable != null)
selectList = Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Select(x => new SelectListItem() { Value = x.ToString(), Text = x.ToString(), Selected = currentKey != null && (int)(object)x == (int)(object)currentKey }).ToList();
if (emptyListItem != null)
selectList.Insert(0, emptyListItem);
return selectList;
}
#endregion
 
/// <summary>
/// Returns a collection of SelectListItem for each possible value of an Enum, with a specific list item selected and optionally an empty list item.
/// </summary>
/// <example>
/// <code>
/// ExtensionMethods.ToSelectList<Colors>(2);
/// // or
/// ExtensionMethods.ToSelectList<Colors>(2, false); if you don't want the empty list item
/// </code>
/// </example>
/// <param name="currentKey">The Guid value of the list item that should be selected by default.</param>
/// <param name="includeEmptyListItem">Whether or not a default list item should be the first list item before those from the collection.</param>
public static IList<SelectListItem> ToSelectList<TEnum>(int currentKey, bool includeEmptyListItem = true) where TEnum : struct
{
TEnum enumCurrentKey = (TEnum)Enum.ToObject(typeof(TEnum), currentKey);
return ToSelectList<TEnum>(enumCurrentKey, includeEmptyListItem ? DefaultEmptySelectListItem : null);
}
 
/// <summary>
/// Returns a collection of SelectListItem for each possible value of an Enum, and optionally an empty list item.
/// </summary>
/// <example>
/// <code>
/// ExtensionMethods.ToSelectList<Colors>();
/// // or
/// ExtensionMethods.ToSelectList<Colors>(false); if you don't want the empty list item
/// </code>
/// </example>
/// <param name="includeEmptyListItem">Whether or not a default list item should be the first list item before those from the collection.</param>
public static IList<SelectListItem> ToSelectList<TEnum>(bool includeEmptyListItem = true) where TEnum : struct
{
return ToEnumSelectList<TEnum>(null, includeEmptyListItem ? DefaultEmptySelectListItem : null);
}
 
/// <summary>
/// Returns a collection of SelectListItem for each possible value of an Enum, with a specific list item selected and optionally an empty list item.
/// </summary>
/// <example>
/// <code>
/// // Useful when your enum is a nullable viewmodel
/// Colors? viewModel = null;
/// ExtensionMethods.ToSelectList(viewModel)
/// </code>
/// </example>
/// <param name="currentKey">The Guid value of the list item that should be selected by default.</param>
/// <param name="includeEmptyListItem">Whether or not a default list item should be the first list item before those from the collection.</param>
public static IList<SelectListItem> ToSelectList<TEnum>(TEnum? currentKey, bool includeEmptyListItem = true) where TEnum : struct
{
return ToEnumSelectList(currentKey, includeEmptyListItem ? DefaultEmptySelectListItem : null);
}
 
/// <summary>
/// Returns a collection of SelectListItem for each possible value of an Enum, with a specific list item selected and optionally an empty list item.
/// </summary>
/// <example>
/// <code>
/// Colors.Green.ToSelectList();
/// // or
/// Colors.Green.ToSelectList(false); if you don't want the empty list item
/// // or
/// var color = Colors.Green;
/// color.ToSelectList();
/// </code>
/// </example>
/// <param name="includeEmptyListItem">Whether or not a default list item should be the first list item before those from the collection.</param>
public static IList<SelectListItem> ToSelectList<TEnum>(this TEnum currentKey, bool includeEmptyListItem = true) where TEnum : struct
{
return ToSelectList(currentKey, includeEmptyListItem ? DefaultEmptySelectListItem : null);
}
/// <summary>
/// Returns a collection of SelectListItem for each possible value of an Enum, with a specific list item selected and a custom empty list item.
/// </summary>
/// <example>
/// <code>
/// Colors.Green.ToSelectList(new SelectListItem() {Text = "~~ Pick One!!! ~~", Value = string.Empty}).Dump();
/// </code>
/// </example>
/// <param name="emptyListItem">The list item to use as the first list item before those from the collection.</param>
public static IList<SelectListItem> ToSelectList<TEnum>(this TEnum currentKey, SelectListItem emptyListItem) where TEnum : struct
{
return ToEnumSelectList<TEnum>(currentKey, emptyListItem);
}
 
private static IList<SelectListItem> ToEnumSelectList<TEnum>(TEnum? currentKey, SelectListItem emptyListItem) where TEnum : struct
{
IList<SelectListItem> selectList;
if (typeof(TEnum).GetCustomAttributes(typeof(FlagsAttribute), false).Any())
selectList = Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Select(x => new SelectListItem() { Value = x.ToString(), Text = x.ToString(), Selected = currentKey != null && ((int)(object)x & (int)(object)currentKey) == (int)(object)x }).ToList();
else
selectList = Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Select(x => new SelectListItem() { Value = x.ToString(), Text = x.ToString(), Selected = currentKey != null && (int)(object)x == (int)(object)currentKey }).ToList();
 
if (emptyListItem != null)
selectList.Insert(0, emptyListItem);
return selectList;
}
}

Revised the logic to not depend on strongly typed keys as String and Guid. Will now take any type that exposes a ToString() method.

Modified the Enum extension method to correctly handle Enums behaving as Flags (Must have the [Flags] attribute decorating the enum definition).

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.