Populating CheckBoxListFor Options from ViewBag

Sep 3, 2012 at 5:30 PM

I'm using MVC4 with MVC Controls Toolkit's CheckBoxListFor and MVC4's DropDownListFor controls.  I've noticed that CheckBoxListFor is much less flexible in allowing dynamic objects (like ViewBag) as input for the checkbox list options, even when manually casted.  I've had to add my list of options to my viewmodel for CheckBoxListFor, whereas with DropDownListFor I can just pull them from the ViewBag.

Does anyone know of a better way to get CheckBoxListFor and ChoiceList to play nice with ViewBag?  If not, that's a feature that would be helpful for me.

Coordinator
Sep 4, 2012 at 6:35 AM

If your problem is building ChoiceList you can do it also taking data from the ViewBag:

ChoiceListHelper.Create(
              WhateverSource as MyType, (t => t.Code), (t => t.Name))

 

The above creates the choice list from any source included the ViewBag(no need to put the list of options in the ViewModel), but you have to cast them. You cant take it automatically from the viewbag, if you want to specify Value and display values with lambda expressions instead that with strings. Using lambda expressions instead of strings avoid errors and help in maintaining the code....infact suppose you change a property name, You can easily find wrong lambda expressions because of compilation errors, while properies specified with string are difficult to find since they just cause runtime errors

Sep 4, 2012 at 4:31 PM
Edited Sep 4, 2012 at 4:31 PM

I'm still not having any luck.

If I do it like this:

@Html.CheckBoxListFor(model => model.StudentSectionID, ChoiceListHelper.Create(ViewBag.AllStudentSectionID as List<CourseManagement.ViewModels.AttendanceStudentSectionList>, o => o.StudentSectionID, o => o.StudentName))

, I get a NullReferenceException in ImportFromModel().

If I just specify the name of my class without the List<> wrapping, like

@Html.CheckBoxListFor(model => model.StudentSectionID, ChoiceListHelper.Create(ViewBag.AllStudentSectionID as CourseManagement.ViewModels.AttendanceStudentSectionList, o => o.StudentSectionID, o => o.StudentName))

, I get an error that the type arguments cannot be inferred from usage.

I tried explicitly casting rather than using the "as" keyword but I get the same errors.  Specifying my Code and Name parameters as strings instead of using Lambda expressions doesn't work either.

Coordinator
Sep 5, 2012 at 3:17 AM

This happens when there is a type mismatch. Typically,

o.StudentSectionID and model.StudentSectionID

 have different types (often it happens one is int and the other is int?...wich are different types).

 

Anothe doubt...it seems that  List<CourseManagement.ViewModels.AttendanceStudentSectionList>....doesnt make sense!!

there I expect something liske List<T> where T is the single element of the list...while  the name AttendanceStudentSectionList look like the name of a collection itself not like the name of the item of a collection.

If you put ....as IEnumerable<TypeOfSingleItem> it should work.

Sep 13, 2012 at 3:37 AM

I actually had a poor naming scheme in my earlier example. I renamed AttendanceStudentSectionList to AttendanceStudentSectionListItem to better reflect it was a single item.

In the end, your last comment proved to be the fix.  If I pass the item my query results into ViewBag as an IEnumerable<AttendanceBulkCreateStudentListItem> rather than a List<AttendanceBulkCreateStudentListItem> and use

@Html.CheckBoxListFor(model => model.StudentSectionID, ChoiceListHelper.Create(ViewBag.AllStudentSectionID as IEnumerable, o => o.StudentSectionID, o => o.StudentName))

in my Razor template it works fine.

Thanks for your help and the module.