I realize this question is already answered, but I was beating my head against a wall dealing with this very issue for the past day trying to figure out why the example above works fine but my code didn't.
It turns out that if you try to put the select list into your ViewData or ViewBag using the same name as the property being set, then client-side validation won't work. The drop-down will populate, though, so it's highly nonintuitive.
// Do NOT do this:
// In the controller:
ViewBag.ItemID = Database.Items.Select(i => new SelectListItem(){Value = i.ID, Text = i.Name});
// In the view:
@Html.DropDownList("ItemID")
// Instead DO this
// In the controller:
ViewBag.ItemIDList = Database.Items.Select(i => new SelectListItem(){Value = i.ID, Text = i.Name});
// In the view:
@Html.DropDownListFor(m => m.ItemID, (IEnumerable<SelectListItem>)ViewBag.ItemIDList)
While the former yields a perfectly functional drop-down, it somehow just doesn't get client-side validation. If you inspect the HTML, all the attributes on the 'select' element just aren't there.
This is completely opposed to the way every other field or editor populates in MVC, since you can set defaults and current values by setting ViewBag.ItemName = "Bob" and if you have a "ItemName" textbox it will populate with "Bob".
Hopefully me posting this will save someone the same hours-long headache.