Reputation: 5670
I am showing an enum as dropdown list in my Edit view
like this:
public enum PaymentType
{
Self=1,
Insurer=2,
PrivateCompany=3
}
public PaymentType PaymentTypeSelected { get; set; }
ViewBag.EnumList = Patient.PaymentType.Insurer.ToSelectList();
patient.PaymentTypeSelected=Patient.PaymentType.Insurer;
@Html.DropDownListFor(m => m.PaymentTypeSelected,
ViewBag.EnumList as SelectList)
public static System.Web.Mvc.SelectList ToSelectList<TEnum>(this TEnum obj)
where TEnum : struct, IComparable, IFormattable, IConvertible
{
return new SelectList(Enum.GetValues(typeof(TEnum)).OfType<Enum>()
.Select(x => new SelectListItem
{
Text = Enum.GetName(typeof(TEnum), x),
Value = (Convert.ToInt32(x)).ToString()
}), "Value", "Text");
}
<select data-val="true"
data-val-required="The PaymentTypeSelected field is required."
id="ptype" name="PaymentTypeSelected">
<option value="1">Self</option>
<option value="2">Insurer</option>
<option value="3">PrivateCompany</option>
</select>
It all looks okay to me, but the dropdown does not show default selected value (in my case Insurer
). Can any one point out what I am doing wrong here?
Upvotes: 1
Views: 2384
Reputation: 120
A SelectList
can takes 4 arguments, where the last argument selectedValue
is an object of whatever type is in your list. So you can try like the following:
ViewBag.yourEnumList= new SelectList(enumList, "Value", "Text", selectedValue);
Or, You can apply this in your extension function
Upvotes: 0
Reputation: 141462
Here it is as a working DotNetFiddle.
In short, you need to make sure that both the Value
property of each SelectListItem
and the PaymentTypeSelected
property are pulling from the same Enum conversion. You were doing int
for the Value
and string
for the PaymentTypeSelected
. Change your extension to this and you're golden.
public static class MyExtensions
{
public static SelectList ToSelectList<TEnum>(this TEnum obj)
where TEnum : struct, IComparable, IFormattable, IConvertible
{
var items = Enum.GetValues(typeof (TEnum))
.OfType<Enum>()
.Select(x => new { Text = x.ToString() })
.Select(x => new SelectListItem
{
Text = x.Text,
Value = x.Text
});
return new SelectList(items, "Value", "Text");
}
}
Upvotes: 3
Reputation: 4107
Try this...
@Html.DropDownListFor(m => ((int)m.PaymentTypeSelected).ToString(), ViewBag.EnumList as SelectList)
Upvotes: 0
Reputation: 38367
As Stephen pointed out, this won't work if you use the DropDownListFor, as the model binding prefers the m=>m.SomeProperty
over the constructor parameter.
You can use the SelectList constructor that takes a 4th object parameter to indicate the selected value: https://msdn.microsoft.com/en-us/library/dd492553(v=vs.118).aspx
// in controller we'll pass the desired selected value to extension method:
ViewBag.EnumList = Patient.PaymentType.Insurer.ToSelectList(Patient.PaymentType.Insurer);
// update method to support this parameter
public static System.Web.Mvc.SelectList ToSelectList<TEnum>(this TEnum obj, object selectedValue)
where TEnum : struct, IComparable, IFormattable, IConvertible // correct one
{
return new SelectList(
Enum.GetValues(typeof(TEnum)).OfType<Enum>()
.Select(x =>
new SelectListItem
{
Text = Enum.GetName(typeof(TEnum), x),
Value = (Convert.ToInt32(x)).ToString()
}
)
,"Value", "Text"
,(int)selectedValue); // pass selected value to SelectList constructor
}
I've made one edit to add (int)
, which is somewhat of a dirty cast since we're coming from an object
. This of course can be improved upon.
Upvotes: 2