ASP.NET mvc : populate (bind data) in listbox

2019-02-27 10:47发布

问题:

I need to populate two listboxes with data from a database. But I need to display two listboxes in one view, so I created a ListBoxModel class.

public class ListboxModel
{
    public ListBox LB1 { get; set; }
    public ListBox LB2 { get; set; }
}

And in my Controller:

public ActionResult IndexStudents(Docent docent, int lessonid, int classid)
    {
        var MyListBox = new ListboxModel
        {
            LB1 = new ListBox(docent.ReturnStudentsNormal(lessonid, classid),
            LB2 = new ListBox(docent.ReturnStudentsNoClass(lessonid, classid)
        };
        return View(MyListBox);
    }

But this code does not work, how can I bind the data to the listboxes? So I'd like to use 2 models, one for each listbox... one with normal students and one with students who are not subscribed for lessons. How could I do that? And what code do I have to write in my view? Something like:

<div class="editor-field">
     <%: Html.ListBox("IndexStudentsNormal", Model.LB1) %> 

<div class="editor-field">
      <%: Html.ListBox("IndexStudentsNoClass", Model.LB2) %> 

The listbox has to be a listbox with multiple colums so that it can contain the name, sirname, class, teacher of the student.

Student is an object, I'd like to display student.Name, student.Sirname, student.Class, and so on in that listbox.

So can I use an object in a ListBox, or do I have to convert everything to strings?

How can I do that?

Thanks in advance!

回答1:

Based on Jason's answer, the first line in your view should include:

<%@ Inherits="System.Web.Mvc.ViewPage<StudentModel>" %>

This tells your view that "Model" is of type StudentModel. If there's other bits in this first line (Title, Language, MasterPageFile, etc), they're fine to stay there.


-- edit: add longish comments --

The thing to remember is that a SelectListItem has three required parts: Value, Text, and Selected. Value is the key, so something like StudentId or DocentId. Text is displayed in the list, so something like StudentName or DocentName. Selected indicates whether this item is selected in the list, typically false.

Right now it looks like you have methods that only return a list of the student names (Docent.ReturnStudentsNormal() and Docent.ReturnStudentsNoClass()). I would have these methods return a list of key-value pairs, key being StudentId and value being StudentName.

Then you can change your model class to be

public class StudentModel
{
  List<SelectListItem> NormalStudents;
  List<SelectListItem> StudentsNoClass;
}

and in your controller

public ActionResult IndexStudents(Docent docent, int lessonId, int classId)
{
  var studentModel = new StudentModel();

  var normalStudents = docent.ReturnStudentsNormal(lessonId, classId);
  foreach (var student in normalStudents)
  {
    studentModel.NormalStudents.Add(new SelectListItem() {Value = student.Key, Text = student.Value});
  }

  var studentsNoClass = docent.ReturnStudentsNormal(lessonId, classId);
  foreach (var student in studentsNoClass)
  {
    studentModel.StudentsNoClass.Add(new SelectListItem() {Value = student.Key, Text = student.Value});
  }

  return View(studentModel);
}

Now you'll be able to use these properties on your model directly for Html.ListBox().



回答2:

The model shouldn't contain a ListBox, it should just contain the lists of students. The trick is to keep the Model as simple as possible, it should really only be a bunch of property getters and setters. The view is responsible for binding a Model's properties to HTML elements.

Model:

public class StudentModel
{
  public IList<string> NormalStudents {get;set;}
  public IList<string> NoClassStudents {get;set;}
}

Controller:

public ActionResult IndexStudents(Docent docent, int lessonid, int classid)
{
    var studentModel = new ListboxModel
    {
       NormalStudents = docent.ReturnStudentsNormal(lessonid, classid),
       NoClassStudents = docent.ReturnStudentsNoClass(lessonid, classid)
    };

    return View(studentModel);
}

View:

<div class="editor-field">
    <%: Html.ListBox("IndexStudentsNormal", Model.NormalStudents) %>
  </div>

  <div class="editor-field">
    <%: Html.ListBox("IndexStudentsNoClass", Model.NoClassStudents) %>
  </div>