Luke101
Luke101

Reputation: 65238

What is wrong with my Dropdownlist

The dropdown list will not select the value I need

 Dictionary<int,int> RowDict = new Dictionary<int, int>();
 for (int i = 1; i < 11; i++)
 {
      RowDict.Add(i, i);
 }
 var rows = new SelectList(RowDict, "Key", "Value", 6);
 ViewBag.Rows = rows;

here is the code in the view:

  <div class="editor-label">
       @Html.LabelFor(m => m.Rows)
  </div>

 <div class="editor-field">
      @Html.DropDownListFor(m => m.Rows, (SelectList)ViewBag.Rows)
      @Html.ValidationMessageFor(m => m.Rows)
 </div>

When I run the code 6 is not selected. Can you see any errors in this code? The first value is selected.

Upvotes: 2

Views: 280

Answers (3)

Abbas
Abbas

Reputation: 14432

@Matthieu , I tested your approach and also my own way where I use the Controller instead to fill the Dictionary and the SelectList. Then I make the View inherit from the model and show the DropDownList. But both won't work. Wouldn't it then be easier to pass the SelectList through the ViewData and then show it in the View? Example:

Controller

var rowDict = new Dictionary<int, int>(); 
for (var i = 1; i < 11; i++)
    rowDict.Add(i, i);
var rows = new SelectList(rowDict, "Key", "Value", 6);
ViewData["Rows"] = rows;
return View();

View

<%: Html.DropDownList("ItemsDropDown", (SelectList)ViewData["Rows"]) %>

Edit: Thanks to Ukko for the tip of the selected parameter to be a string, the code I tried worked as well, and you don't need to fill the SelectList through the constructor of the ViewModel. The idea alone is actually illogical as it is in the controller you need to fill the ViewModel and pass this to the View:

Model:

public class HomeModel
{
    public SelectList Rows { get; set; }
    public String Selected { get; set; }
}

Controller

var rowDict = new Dictionary<int, int>();
for (var i = 1; i < 11; i++)
    rowDict.Add(i, i);
var rows = new SelectList(rowDict, "Key", "Value");
var model = new HomeModel { Rows = rows, Selected = "6" };
return View(model);

View:

<div class="editor-field">
    <%: Html.DropDownListFor(model => model.Rows, Model.Rows, Model.Selected) %>
</div>

Upvotes: 0

Ukko
Ukko

Reputation: 2266

As a first step you need to make the selectedValue in your SelectList constructor into a string rather than an integer.

var rows = new SelectList(RowDict, "Key", "Value", "6");

instead of

var rows = new SelectList(RowDict, "Key", "Value", 6);

Upvotes: 0

Matthieu
Matthieu

Reputation: 4620

m => m.Rows suggests there is a model involved. It works better if you do the initialization with the rows from the model, not the view bag.

A really quick and dirty initialization like this :

   public class TestModel
   {
      public TestModel()
      {
         Dictionary<int, int> RowDict = new Dictionary<int, int>(); 
         for (int i = 1; i < 11; i++) 
         { 
            RowDict.Add(i, i); 
         }

         this.Rows = new SelectList(RowDict, "Key", "Value");
         this.SelectedId = "6"; // binding to selection works as a String
      }

      public SelectList Rows { get; set; }

      public string SelectedId { get; set; }

   }

And this in the controller where the view is requested :

return View(new TestModel());

And a view starting with something like :

@model <insert_appropriate_anmespace_here>.TestModel

...

@Html.DropDownListFor(m => m.Rows, Model.Rows, Model.SelectedId) 

makes it work. You can adapt this code and initialization the way you want, as long as you remember that models are passed by value to the view, reason why I setup my init in the constructor (every time a TestModel is created, the Select List will get initialized).

Also you can make a mix of viewbag and model and have it to work, I wouldnt recommend it for readability.

Upvotes: 2

Related Questions