Setting selected item in DropDownList - asp.net-mvc

I have a list of Deviation items getting from database. The list contains Severity which may be null. Thats why I made the SeverityNotNull property to transform null values to -1. BTW Severity can be 0-3.
I would like to show Deviations items in which each Severity should be a DropdownList line by line. And of course in the DropdownList the appropriate item should be selected.
my ViewModel is:
[MetadataType(typeof(DeviationMetaData))]
public partial class Deviation {
public int SeverityNotNull {
get { return Severity == null ? -1 : Severity.Value; }
}
...
}
public class DeviationMetaData {
public Nullable<int> Severity { get; set; }
...
}
public class DeviationViewModel {
public Deviation Dev { set; get; }
public IEnumerable<Deviation> Deviations {
get {
DeviationRepository dm = new DeviationRepository();
return dm.GetAll;
}
}
public DeviationViewModel() {
WindowsIdentity current = WindowsIdentity.GetCurrent();
string name = current.Name.Split(new[] { '\\' })[1];
Dev = new Deviation { CreatedBy = name, CreatedDate = DateTime.Now };
}
}
my Controller is:
public ActionResult Index() {
IList<SelectListItem> items = new List<SelectListItem> {
new SelectListItem{Text = "", Value = "-1"},
new SelectListItem{Text = "Minor", Value = "1"},
new SelectListItem{Text = "Major", Value = "2"},
new SelectListItem{Text = "Critical", Value = "3"}
};
ViewBag.SelectSeverity = new SelectList(items, "Value", "Text");
return View( new DeviationViewModel() );
}
my View is:
#model DeviationViewModel
#using (Html.BeginForm()) {
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.Dev.Severity)
</th>
</tr>
#foreach (var item in Model.Deviations) {
<tr>
<td>
#Html.DropDownListFor(modelItem => item.SeverityNotNull, (SelectList)ViewBag.SelectSeverity)
</td>
</tr>
}
</table>
</fieldset>
}
</div>
I checked the SeverityNotNull values and they are correct. In the result there are the Dropdownlists, but nothing is selected. That is the problem. Could you give me some idea? Thanks.

It is not necessary to create a SeverityNotNull property. A SelectList can contain an option with a null value that if selected will post back null. You have multiple other problems as well including using a foreach loop that will render <selects> with duplicate name attributes (wont bind on postback) and duplicate id attributes (invalid html).
Start by creating a view model to represent a Deviation
public class DeviationVM
{
public int ID { get; set; }
public int? Severity { get; set; }
// other properties of the Deviation data model that you want to edit/display
}
Controller
public ActionResult Index()
{
// Get your deviations and map to the view model
List<DeviationVM> model = dm.GetAll().Select(d => new DeviationVM
{
ID = d.ID,
Severity = d.Severity
}).ToList();
// create your select list (
var severityList = new[] { new { ID = 1, Name = "Minor" }, new { ID = 2, Name = "Major" }, new { ID = 2, Name = "Critical" } };
ViewBag.SeverityList = new SelectList(severityList, "ID", "Name");
return View(model)
}
public ActionResult(List<DeviationVM> model)
{
...
}
View
#model List<DeviationVM>
#using (Html.BeginForm()) {
....
for(int i = 0; i < Model.Count; i++)
{
#Html.HiddenFor(m => m[i].ID)
#Html.DropDownListFor(m => m[i].Severity, (SelectList)ViewBag.SeverityList, "Text for null value")
}
Note the use of the for loop which generates <select name="[0].Severity" ..> <select name="[1].Severity" ..> which are correctly named with indexers and will be bound on post back. Note also the use of the overload of #Html.DropDownListFor() which will generate the options as <option value>Text for null value</option> <option value="1">Minor</option> .... The first option does not have a value so if it is selected the value of property Severity will be null on postback.
Note also that if the value of property Severity is initiallt null then the first option will be selected by default. If the value is 2, then the 3rd option will be selected by default.

Related

How to change a variable (MVC)

I want to change values in the table from True, false To>>> Yes, No
,honesty I'm confused
enter image description here
enter image description here
You can use a select list for this.
Edit like this your model:
public class ExampleViewModel : BaseCEViewModel
{
public ExampleViewModel()
{
BoolList = new List<SelectListItem>();
BoolList.Add(new SelectListItem
{
Text = "Yes",
Value = "true"
});
BoolList.Add(new SelectListItem
{
Text = "No",
Value = "false"
});
SelectedBools = new List<bool>();
}
public List<SelectListItem> BoolList { get; set; }
public List<bool> SelectedBools { get; set; }
}
Now you can use a dropdownlist in your page, if you give same name to your dropdowns, values will add the SelectedBools Variable.
#Html.DropDownList("SelectedBools", Model.BoolList, new { #class = "form-control select2", placeholder = "...Select..." })
As we clarify that you want text not a dropdown in your view
Don't use Html.DisplayFor(x => x.Active)
Try using if
Note: As you specify the variable to accepts null value. First check for null then use if statement
View
foreach(var item in Model)
{
<tr>
<td>
if(item.Active != null)
{
if(Convert.ToBoolean(item.Active))
{
<p>Yes</p>
}
else
{
<p>No</p>
}
}
</td>
<td> ... </td>
</tr>
}

How to shorten the url when using pagination and filtering with multiple checkboxes

I am using PagedList for server side paging, and also have a textbox in the view for filtering the data, along with checkboxes to determine which fields in my model to filter based on the search text.
My current code is
View model
public class SearchPagingViewModels
{
public IPagedList<AllResolution> Resolutions { get; set; }
public string Keyword { get; set; } // serach text
public bool IsResYearChecked { get; set; } // used to filter the ResolutionYear field
public bool IsResNumChecked { get; set; } // used to filter the ResolutionNumber field
public bool IsResTextChecked { get; set; } // used to filter the ResolutionText field
}
Controller
public ViewResult Index(int? page string keyword, bool? isResYearChecked, bool? isResNumChecked, bool? isResTextChecked)
{
int pageSize = 25;
int pageNumber = (page ?? 1);
bool searchYear = isResYearChecked.GetValueOrDefault();
....
IQueryable<> resolutions = db.AllResolutions;
if (searchKeyword != null)
{
if (searchYear)
{
resolutions = resolutions.Where(x => x.ResolutionYear.Contains(searchKeyword));
}
....
}
resolutions = resolutions.OrderBy(c => c.ResolutionYear).ThenBy(c => c.ResolutionNumber);
SearchPagingViewModels model = new SearchPagingViewModels
{
Keyword = keyword,
IsResYearChecked = searchYear,
....
Resolutions = resolutions.ToPagedList(pageNumber, pageSize)
};
return View(model);
}
View
#model SearchPagingViewModels
....
#using (Html.BeginForm("Index", "Resolutions", FormMethod.Get))
{
#Html.LabelFor(m => m.Keyword)
#Html.TextBoxFor(m => m.Keyword)
#Html.LabelFor(m => m.IsResYearChecked)
#Html.CheckBoxFor(m => m.IsResYearChecked)
// .. ditto for IsResNumChecked etc
<input type="submit" value="search" />
}
<table>
<thead>
....
</thead>
<tbody>
#foreach (var task in Model.Resolutions)
{
// .... build table rows
}
</tbody>
</table>
#Html.PagedListPager(Model.Resolutions, page => Url.Action("Index", new { page, Keyword = Model.Keyword, IsResYearChecked = Model.IsResYearChecked, IsResNumChecked = IsResNumChecked IsResTextChecked = Model.IsResTextChecked }))
While this works, the issue is that the for generates a long and ugly query string, for example
.../Index?Keyword=someText&IsResYearChecked=true&IsResYearChecked=false&IsResNumChecked=false&IsResTextChecked=true&IsResTextChecked=false
And now I want to add additional bool properties for filtering the records making it even worse and potentially exceeding the query string limit.
Is there a way to shorten the URL? Would this be related to routing? Would a new ViewModel be in order to accomplish this?
Your could replace all your bool properties with an enum marked with the [Flags] attribute where each value in the enum represents a property in your model to search.
[Flags]
public enum FilterProperties
{
None = 0,
ResolutionYear = 1,
ResolutionNumber = 2,
ResolutionText = 4,
.... // more properties
}
and the view model will be
public class SearchPagingViewModels
{
public string Keyword { get; set; }
public FilterProperties Filter { get; set; }
public IPagedList<AllResolution> Resolutions { get; set; }
}
The controller method then becomes
public ViewResult Index(int? page string keyword, FilterProperties filter = FilterProperties.None)
{
IQueryable<AllResolution> resolutions = db.AllResolutions;
if (searchKeyword != null)
{
if (filter.HasFlag(FilterProperties.ResolutionYear)
{
resolutions = resolutions.Where(x => x.ResolutionYear.Contains(feyword));
}
// .... more if blocks for other enum values
}
resolutions = resolutions.OrderBy(c => c.ResolutionYear).ThenBy(c => c.ResolutionNumber);
SearchPagingViewModels model = new SearchPagingViewModels
{
Keyword = keyword,
Filter = filter,
Resolutions = resolutions.ToPagedList(pageNumber, pageSize)
};
return View(model);
}
You view will then be
#using (Html.BeginForm("Index", "Resolutions", FormMethod.Get))
{
#Html.LabelFor(m => m.Keyword)
#Html.TextBoxFor(m => m.Keyword)
#Html.ValidationMessageFor(m => m.Keyword)
#Html.HiddenFor(m => m.Filter)
foreach (Enum item in Enum.GetValues(typeof(Tables.Controllers.FilterProperties)))
{
if (item.Equals(Tables.Controllers.FilterProperties.None))
{
continue;
}
<div>
<label>
<input type="checkbox" value="#((int)(object)item)" checked=#Model.Filter.HasFlag(item) />
<span>#item</span>
</label>
</div>
}
<span id="filtererror" class="field-validation-error" hidden >Please select at least one property to search</span>
<input type="submit" value="Search" />
}
<table>
....
</table>
#Html.PagedListPager(Model.Resolutions, page => Url.Action("Index", new { page, Keyword = Model.Keyword, Filter = (int)Model.Filter }))
And then use javascript to andles the forms .submit() event to update the hidden input value for Filter (note I have also assumed that you want at least one checkbox selected if the value of Keyword is not null)
<script>
var checkboxes = $('input:checkbox');
var keyword = $('#Keyword');
$('form').submit(function () {
var filter = 0;
// validate at least one checkbox must be checked if Keyword has a value
if (keyword.val() && checkboxes.filter(':checked').length == 0) {
$('#filtererror').show();
return false;
}
$.each(checkboxes, function () {
if ($(this).is(':checked')) {
filter += Number($(this).val());
}
// disable checkboxes to prevent their value being added to the query string
$(this).prop('disabled', true);
})
$('#Filter').val(filter);
})
checkboxes.click(function () {
if (keyword.val() && checkboxes.filter(':checked').length == 0) {
$('#filtererror').show();
} else {
$('#filtererror').hide();
}
})
</script>
Your URL (based on ResolutionYear and ResolutionText being checked) will now be
.../Index?Keyword=someText&Filter=5
instead of
.../Index?Keyword=someText&IsResYearChecked=true&IsResYearChecked=false&IsResNumChecked=false&IsResTextChecked=true&IsResTextChecked=false

Asp .Net MVC, how to put/include values to DropDownListFor?

I am following this tutorial which works very fine. But the problem is that it only provides key and without it own value (As shown in the picture below). How to include values to each of these keys?
Inspected Elements (Picture)
Model
[Required( ErrorMessage = "Selection is a MUST" )]
public string SelectedItem { get; set; }
private List<string> _items;
public List<string> Items
{
get
{
_items = new List<string>();
_items.Add("One");
_items.Add("Two");
_items.Add("Three");
return _items;
}
}
Controller
public class HomeController : Controller
{
//Render Action
[HttpGet]
public ViewResult Index()
{
DropdownListModel model = new DropdownListModel();
return View(model);
}
//Process Action
[HttpPost]
public ViewResult Index(DropdownListModel model)
{
//TODO: Validate using if(ModelState.IsValid) and process information
return View(model);
}
}
View
<div>
<!--Render the DropDownListmodel -->
#using (Html.BeginForm())
{
<p>#Html.ValidationSummary()</p>
<p>Select an Item : #Html.DropDownListFor(x => x.SelectedItem, new SelectList(Model.Items), "--Choose any Item--" )</p>
<input type="submit" value="Submit" />
}
<!-- Display Selected Item -->
#if (!String.IsNullOrWhiteSpace(Model.SelectedItem))
{
<span>Selected Item : #Model.SelectedItem</span>
}
</div>
What I Attempted
I replaced the codes in models with the code below. But I have error saying Models.KeyValueModel: : EntityType 'KeyValueModel' has no key defined. Define the key for this EntityType.
KeyValueModels: EntityType: EntitySet 'KeyValueModels' is based on type 'KeyValueModel' that has no keys defined.
public List<KeyValueModel> Items
{
get
{
List<KeyValueModel> item = new List<KeyValueModel>();
var n = new KeyValueModel();
n.Key = "1";
n.Value = "One";
item.Add(n);
n = new KeyValueModel();
n.Key = "2";
n.Value = "Second";
item.Add(n);
n = new KeyValueModel();
n.Key = "3";
n.Value = "Three";
item.Add(n);
return item;
}
}
You need to specify on your HttpGet request your Key Value pair like this one:
DropdownListModel model = new DropdownListModel();
model.ItemList = new List<SelectListItem>()
{
new SelectListItem { Text = "One", Value = "1" },
new SelectListItem { Text = "Two", Value = "2" }
};
Then on your model, add this:
public IEnumerable<SelectListItem> ItemList { get; set; }
And on your View:
#Html.DropDownListFor(x => x.SelectedItem, Model.Items, "--Choose any Item--" )
add the Model as:
public string nameofdropdown{ get; set; }
public IEnumerable<SelectListItem> listyouwanttodisplay{ get; set; }
In get method:
Model model=new Model;
List<SelectListItem> cd = Get() //call here----
var additionaldata= new SelectListItem()
{
Value = null,
Text = "--- place holder---"
};
cd.Insert(0, additionaldata);
model.listyouwanttodisplay=cd;
return View (model);
In View:
<div>
#Html.DropDownListFor(model => model.nameofdropdown, new
SelectList(Model.listyouwanttodisplay, "Value","Text"),htmlAttributes: new { #class = "form-control" })
</div>

Passing Model data from View to Controller

I am trying to pass the Model data from a View (and PartialView within the View) back to the Controller upon HttpPost. (Adapted from Pass SelectedValue of DropDownList in Html.BeginForm() in ASP.NEt MVC 3)
Why? I want to show a list of assets each with a DropDownList and number of options. Upon submission of form to read the selected items from DropDownList.
My 2 (simplified) models:
public class Booking
{
public int BookingID { get; set; }
public int StoreID { get; set; }
...
public IEnumerable<AssetShort> Assets { get; set; }
}
and
public class AssetShort
{
public int AssetID { get; set; }
....
public int SelectedAction { get; set; }
public IEnumerable<SelectListItem> ActionList { get; set; }
}
In my Booking Controller > Create I build the List:
public ActionResult Booking(int id)
{
// get myBag which contains a List<Asset>
// booking corresponds to 'id'
var myAssets = new List<AssetShort>();
foreach (var a in myBag.Assets)
{
var b = new AssetShort();
b.AssetID = a.ID;
b.SelectedAction = 0;
b.ActionList = new[]
{
new SelectListItem { Selected = true, Value = "0", Text = "Select..."},
new SelectListItem { Selected = false, Value = "1", Text = "Add"},
new SelectListItem { Selected = false, Value = "2", Text = "Remove"},
new SelectListItem { Selected = false, Value = "3", Text = "Relocate"},
new SelectListItem { Selected = false, Value = "4", Text = "Upgrade"},
new SelectListItem { Selected = false, Value = "5", Text = "Downgrade"}
};
myAssets.Add(b);
};
var model = new BookingRequirementsViewModel
{
BookingID = booking.ID,
StoreID = booking.StoreID,
Assets = myAssets.ToList(),
};
return View(model);
My View:
#model uatlab.ViewModels.BookingRequirementsViewModel
#{
ViewBag.Title = "Booking step 2";
}
<h4>Your booking ref. #Model.BookingID</h4>
#using (Html.BeginForm("Booking2", "Booking", FormMethod.Post))
{
<fieldset>
#Html.AntiForgeryToken()
#Html.HiddenFor(model => model.StoreID)
#Html.Partial("_Assets", Model.StoreAssets)
<input type="submit" value="Cancel" class="btn btn-default" />
<input type="submit" value="Next" class="btn btn-default" />
</fieldset>
}
The Partial View includes
#foreach (var item in Model)
{
<tr>
<td>#item.Name</td>
<td>#item.Number</td>
<td>#Html.DropDownListFor(modelItem=>item.SelectedAction, item.ActionList)</td>
</tr>
}
So, all this works fine in the browser and I can select dropdowns for each asset listed but when I submit the only value posted back is the StoreID as it is in a "HiddenFor".
The booking2 controller has the model for a parameter:
public ActionResult Booking2(BookingRequirementsViewModel model)
{
//loop through model.Assets and display SelectedActions
}
Let me make it clear what the problems is - in Booking2 controller the Model is null when viewed in Debug mode and I get error "Object reference not set to an instance of an object."
Any ideas please how to pass back the Model to controller from view?
Regards
Craig
You need to create an EditorTemplate for AssetShort. I also suggest moving ActionList to the BookingRequirementsViewModel so your not regenerating a new SelectList for each AssetShort
The models you have posted aren't making sense. Your controller has var model = new BookingRequirementsViewModel { ..., Assets = myAssets.ToList() }; but in the view you refer to #Html.Partial("_Assets", Model.StoreAssets)? Are these 2 different properties. I will assume that StoreAssets is IEnumerable<AssetShort>
/Views/Shared/EditorTemplates/AssetShort.cshtml
#model AssetShort
<tr>
<td>#Html.DispayFor(m => m.Name)</td>
....
<td>
#Html.DropDownListFor(m => m.SelectedAction, (IEnumerable<SelectListItem>)ViewData["actionList"], "--Please select--")
#Html.ValidationMessageFor(m => m.SelectedAction)
</td>
</tr>
In the main view
#model uatlab.ViewModels.BookingRequirementsViewModel
....
#using (Html.BeginForm()) // Not sure why you post to a method with a different name
{
....
#Html.HiddenFor(m => m.StoreID)
#Html.EditorFor(m => m.StoreAssets, new { actionList = Model.ActionList })
....
}
In the controller
public ActionResult Booking(int id)
{
....
var model = new BookingRequirementsViewModel
{
BookingID = booking.ID,
StoreID = booking.StoreID,
Assets = myBag.Assets.Select(a => new AssetShort()
{
AssetID = a.ID,
SelectedAction = a.SelectedAction, // assign this if you want a selected option, otherwise the "--Please select--" option will be selected
....
})
};
ConfigureViewModel(model); // Assign select list
return View(model);
}
And a separate method to generate the SelectList because it needs to be called in the GET method and again in the POST method if you return the view. Note use the overload of DropDownListFor() to generate the option label (null value) as above, and there is no point setting the Selected property (the value of SelectedAction determines what is selected, not this)
private ConfigureViewModel(BookingRequirementsViewModel model)
{
model.ActionList = new[]
{
new SelectListItem { Value = "1", Text = "Add"},
....
new SelectListItem { Value = "5", Text = "Downgrade"}
};
}
and the POST
public ActionResult Booking(BookingRequirementsViewModel model)
{
if (!ModelState.IsValid)
{
ConfigureViewModel(model); // Re-assign select list
return View(model);
}
// save and redirect
}
I recommend also making SelectedAction nullable with the [Required] attribute so you get client and server side validation
public class AssetShort
{
public int AssetID { get; set; }
....
[Required]
public int? SelectedAction { get; set; }
}

How to show multiple selected with asp.net mvc 3 and ListBoxFor?

I have this VM properties
public IList<Guid> SelectedEligiableCategories { get; set; }
public IList<SelectListItem> EligiableCategories { get; set; }
I have this helpers in my view
#Html.LabelFor(x => x.EligibleCategoryFrmVm.SelectedEligiableCategories, "Eligible Categories:")
#Html.ListBoxFor(x => Model.EligibleCategoryFrmVm.SelectedEligiableCategories, Model.EligibleCategoryFrmVm.EligiableCategories, new { #class = "eligibleCategoryListBox" })
I have this code in my controller
List<SelectListItem> eligibleCategoriesListItems = Mapper.Map<List<EligibleCategory>, List<SelectListItem>>(eligibleCategories);
foreach (var rewardTier in creditCard.RewardTiers)
{
CbRewardTierFrmVm rewardTierFrmVm = new CbRewardTierFrmVm();
rewardTierFrmVm.EligibleCategoryFrmVm.EligiableCategories = eligibleCategoriesListItems;
foreach (var ec in rewardTier.EligibleCategories)
{
rewardTierFrmVm.EligibleCategoryFrmVm.SelectedEligiableCategories.Add(ec.Id);
}
vm.CbRewardTierFrmVm.Add(rewardTierFrmVm);
}
Yet when I load up my view. None of values for my ListBox are selected. I am not sure why. If this was a selectList this would work as it would match up the SelectedEligiableCategories to the value in the list.
I am not sure if this is because there is multiple selects
Edit
<select name="CbRewardTierFrmVm[63b504c0-0f9a-47ba-a8ff-db85f48d5f0f].EligibleCategoryFrmVm.SelectedEligiableCategories" multiple="multiple" id="CbRewardTierFrmVm_63b504c0-0f9a-47ba-a8ff-db85f48d5f0f__EligibleCategoryFrmVm_SelectedEligiableCategories" data-val-required="Must choose at least one eligible category." data-val="true" class="eligibleCategoryListBox ui-wizard-content ui-helper-reset ui-state-default" style="display: none;">
<option value="ed2bb5f9-4565-4f69-ab15-9fca011c0692">Gas</option>
</select>
Do you think it is because I am using http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/ ?
Edit2
I gone ahead and make an example. I must be missing something(not sure what). When I use "Darin Dimitrov" it works.
I switched the example to a dropdown as I am getting the same problem with it as well.
In this example I am not using a viewmodel since my initial assumption was somehow the helper I was using from Steven Sanders might be effecting it so I was going off his example.
This does not seem to be the case as I removed it and still get this problem.
public class Gift
{
public string Name { get; set; }
public double Price { get; set; }
public string SelectedItem { get; set; }
public IList<SelectListItem> Items { get; set; }
}
public ActionResult Index()
{
List<SelectListItem> items = new List<SelectListItem>
{
new SelectListItem {Value = "",Text ="--"},
new SelectListItem {Value = "1",Text ="1"},
new SelectListItem {Value = "2",Text ="2"},
};
var initialData = new[] {
new Gift { Name = "Tall Hat", Price = 39.95, Items = items, SelectedItem = "2" },
new Gift { Name = "Long Cloak", Price = 120.00, Items = items, SelectedItem = "1" }
};
return View("Index3",initialData);
}
#model IList<EditorDemo.Models.Gift>
#{
ViewBag.Title = "Index3";
}
#for (int i = 0; i < Model.Count; i++)
{
#Html.DropDownListFor(x => x[i].SelectedItem, new SelectList(Model[i].Items, "Value", "Text"))
}
It seems to not be able to handle when you put it in forloop and try it make more than one dropdown list.
The following works for me.
Model:
public class MyViewModel
{
public IList<Guid> SelectedEligiableCategories { get; set; }
public IList<SelectListItem> EligiableCategories { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
SelectedEligiableCategories = new[]
{
// preselect the second and the fourth item
new Guid("35830042-3556-11E1-BCDC-A6184924019B"),
new Guid("4253876A-3556-11E1-BC17-B7184924019B")
}.ToList(),
EligiableCategories = new[]
{
new SelectListItem { Value = "2DA62E3A-3556-11E1-8A0A-9B184924019B", Text = "item 1" },
new SelectListItem { Value = "35830042-3556-11E1-BCDC-A6184924019B", Text = "item 2" },
new SelectListItem { Value = "3D07EBAC-3556-11E1-8943-B6184924019B", Text = "item 3" },
new SelectListItem { Value = "4253876A-3556-11E1-BC17-B7184924019B", Text = "item 4" },
}
};
return View(model);
}
}
View:
#model MyViewModel
#using (Html.BeginForm())
{
#Html.ListBoxFor(
x => x.SelectedEligiableCategories,
Model.EligiableCategories,
new { #class = "eligibleCategoryListBox" }
)
}
Result:
UPDATE:
Now that you have shown an example allowing to illustrate the problem, you could specify the selected item when building the SelectList:
#Html.DropDownListFor(
x => x[i].SelectedItem,
new SelectList(Model[i].Items, "Value", "Text", Model[i].SelectedItem)
)
The reason a value was not preselected was because you were binding the dropdownlist to a list of properties (x => x[i].SelectedItem) whereas in my example I was using a simple property.
And if you wanted to do this with the ListBoxFor helper you could use the following:
#Html.ListBoxFor(
x => x[i].SelectedItems,
new MultiSelectList(Model[i].Items, "Value", "Text", Model[i].SelectedItems)
)
The SelectedItems property becomes a collection and we use a MultiSelectList instead of a SelectList.
The main problem is using
#Html.DropDownListFor
instead of this
#Html.ListBoxFor
Using the DropDownListFor will NOT help you with multiple values, whatever you do and no matter what your model is. Once you use ListBoxFor ... it will automatically just work !

Resources