The selected property in SelectListItem never works (DropDownListFor)

I'm having trouble choosing DropDownList. I read all the related entries and I cannot get a solution.

The actual approach seemed very good to me, because I can check the fields that will be inside the SelectList:

var selectList = new List<SelectListItem>( from variable in someKindOfCollection select new SelectListItem { Selected = variable.Property == selection, Text = variable.Property, Value = variable.Property }); 

Presumably this gives me complete control. After the selectList has been created, I can check the variables using the debugger. Everything is in order, and one of them has the selected attribute selected.

Then I use DropDownListFor to display on the view:

 @Html.DropDownListFor( g => g.SomePropertyInModel , selectList, new { @class = "cssClass" }) 

But this does not work, never ... "Sends" a drop-down menu, but nothing is selected.

Many thanks:)

NEW EXAMPLE First of all, I want to apologize. I hid the information, of course, completely inadvertently. All code happens inside Razor For Loop:

 @foreach (var loopVariable in Model.Collection) { if (Model.SomeCondition != null) { selection = someValue; } var selectList = new List<SelectListItem>( from variable in someKindOfCollection select new SelectListItem { Selected = variable.Property == selection, Text = variable.Property, Value = variable.Property }); @Html.DropDownListFor( g => g.SomePropertyInModel , selectList, new { @class = "cssClass" }) } 

So, this is a fact of selectList - is it a local variable that causes behavior ?. Sorry, I didn’t think so.

+6
source share
8 answers

I think you have the same problem. I looked through the source code to find my solution, and it seems like this is a mistake for me. The next DropDownListFor should help, the key to this is that you pass the selected value to the html helper. Hope this helps.

 public static class SelectExtensions { public static IHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string selectedValue, string optionLabel, object htmlAttributes = null) { return DropDownListHelper(helper, ExpressionHelper.GetExpressionText(expression), selectList, selectedValue, optionLabel, htmlAttributes); } /// <summary> /// This is almost identical to the one in ASP.NET MVC 3 however it removes the default values stuff so that the Selected property of the SelectListItem class actually works /// </summary> private static IHtmlString DropDownListHelper(HtmlHelper helper, string name, IEnumerable<SelectListItem> selectList, string selectedValue, string optionLabel, object htmlAttributes) { name = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name); // Convert each ListItem to an option tag var listItemBuilder = new StringBuilder(); // Make optionLabel the first item that gets rendered if (optionLabel != null) listItemBuilder.AppendLine(ListItemToOption(new SelectListItem() { Text = optionLabel, Value = String.Empty, Selected = false }, selectedValue)); // Add the other options foreach (var item in selectList) { listItemBuilder.AppendLine(ListItemToOption(item, selectedValue)); } // Now add the select tag var tag = new TagBuilder("select") { InnerHtml = listItemBuilder.ToString() }; tag.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); tag.MergeAttribute("name", name, true); tag.GenerateId(name); // If there are any errors for a named field, we add the css attribute ModelState modelState; if (helper.ViewData.ModelState.TryGetValue(name, out modelState)) { if (modelState.Errors.Count > 0) tag.AddCssClass(HtmlHelper.ValidationInputCssClassName); } // Add the unobtrusive validation attributes tag.MergeAttributes(helper.GetUnobtrusiveValidationAttributes(name)); return tag.ToHtmlString(TagRenderMode.Normal); } private static string ListItemToOption(SelectListItem item, string selectedValue) { var tag = new TagBuilder("option") { InnerHtml = HttpUtility.HtmlEncode(item.Text) }; if (item.Value != null) tag.Attributes["value"] = item.Value; if ((!string.IsNullOrEmpty(selectedValue) && item.Value == selectedValue) || item.Selected) tag.Attributes["selected"] = "selected"; return tag.ToString(TagRenderMode.Normal); } } 
+4
source

I would recommend using a view model:

 public ActionResult Index() { var model = new MyViewModel { // this will preselect the item with value = "2.400 €" in the collection SelectedValue = "2.400 €", Values = someKindOfCollection }; return View(model); } 

and in view:

 @Html.DropDownListFor( g => g.SelectedValue, new SelectList(Model.Values, "SomePropertyForValue", "SomePropertyForText"), new { @class = "cssClass" } ) 
+2
source

You must debug your selection list again.

None of your parameter values ​​have selected=selected .

Try hard copying your list to something like

 SelectList = new List<SelectListItem> { new SelectListItem{Text = "600 €", Value="600 €" , Selected = false}, new SelectListItem{Text = "1.200 €", Value="1.200 €" , Selected = false}, new SelectListItem{Text = "2.400 €", Value="2.400 €" , Selected = false}, new SelectListItem{Text = "3.000 €", Value="3.000 €" , Selected = true}, }; 

Using this code and your Html.DropDownFor , SelectList works fine and generates this HTML

 <select id="TheID" name="TheName" class="cssClass"> <option value="600 €">600 €</option> <option value="1.200 €">1.200 €</option> <option value="2.400 €">2.400 €</option> <option value="3.000 €" selected="selected">3.000 €</option> </select> 

From your code, I cannot say whether your comparison compares one of the selected attributes with true or not, but that is probably why your code does not work.

+2
source

I don’t know if this will help anyone, but it solved it for me ....

In my model there was both a collection and a selected value.

I changed my mind:

 @Html.DropDownListFor( g => g.CollectionName, new SelectList(Model.CollectionName, "SomePropertyForValue", "SomePropertyForText", Model.SelectedValue), new { @class = "cssClass" } ) 

to

 @Html.DropDownListFor( g => g.SelectedValue, new SelectList(Model.CollectionName, "SomePropertyForValue", "SomePropertyForText", Model.SelectedValue), new { @class = "cssClass" } ) 

When my first parameter in DropDownListFor referred to the collection, I would get a drop-down list, but the selected value would never get up.

+2
source

The solution to this problem is simpler than we all think ...

All we need to do, when returning the view from the controller, set the property in the view model for the element with which the drop-down list is associated - ie: model.SomePropertyInModel = '5', for example

that way when we do it

 @Html.DropDownListFor( g => g.SomePropertyInModel , selectList, new { @class = "cssClass" }) 

HtmlHelper will automatically select the default value that will be displayed in DropDownList

Simples!

Hope this can help you and everyone else - like me! - who have lost a lot of time to find a solution to this obvious problem.

+2
source

I had a similar problem, and the reason is that I did not set a value for the property in my view model, which was obtained using SelectListItems. You do not need to set the "Selected" property at all. To use the wording from the original example, simply set "SomePropertyOnModel" for the current selection. DropDownListFor will appropriately bind the Select property.

+1
source

My recommendation for DropDownListFor is,

  • has the IEnumerable property of the model (or viewmodel) that is passed to the view. For example, in your case:

     private IEnumerable<SelectListItem> GetListItems() { var selectList = db.YourDBThings .Where(t => t.IsCool == true) .Select(x => new SelectListItem { Value = x.Id.ToString(), Text = x.Name }); return new SelectList(issues, "Value", "Text"); } 
  • Then add this IEnumerable to your object, assuming that you also have a property in your object that has an ONE element (the one to be set as the selected one) that matches one of the "values" in the list:

     FancyViewModel myFancyViewModel = new FancyViewModel(); myFancyViewModel.ListOptions = GetListItems(); myFancyViewModel.SelectedThingId = 3; //this 3 would match one of the value in the list //.... return View(myFancyViewModel); 
  • Then in the view where you get an instance of FancyViewModel that contains a list of elements:

     @model Project.ViewModels.FancyViewModel @*...*@ @Html.DropDownListFor(x=>x.SelectedThingId, Model.ListOptions) 

The first argument to DropDownListFor indicates the TProperty, which contains the field to be selected in the list. The second is the list itself, which comes from the model (although it can be found from anywhere!)

0
source

There is a problem: g.SelectedValue must be a null type in your model.

-1
source

Source: https://habr.com/ru/post/911231/


All Articles