I added some more methods to the code provided by Tyler Garlick’s CheckBoxList for ASP.net MVC to allow a dictionary to be passed in place of a list of SelectListItems and an optional list of selected ids. Anyway, here’s the full class.

using System.Collections.Generic;
using System.Linq;
using System.Text;
  
namespace System.Web.Mvc
{
    public static class CheckBoxListHelper
    {
        public static string CheckBoxList(this HtmlHelper helper, string name, IDictionary<string, string> items)
        {
            return CheckBoxList(helper, name, items, null, null);
        }
  
        public static string CheckBoxList(this HtmlHelper helper, string name, IDictionary<string, string> items, IDictionary<string, object> checkboxHtmlAttributes)
        {
            return CheckBoxList(helper, name, items, null, checkboxHtmlAttributes);
        }
  
        public static string CheckBoxList(this HtmlHelper helper, string name, IDictionary<string, string> items, IEnumerable<string> selectedValues)
        {
            return CheckBoxList(helper, name, items, selectedValues, null);
        }
  
        public static string CheckBoxList(this HtmlHelper helper, string name, IDictionary<string, string> items, IEnumerable<string> selectedValues, IDictionary<string, object> checkboxHtmlAttributes)
        {
            var selectListItems = from i in items
                                  select new SelectListItem
                                             {
                                                 Text = i.Key,
                                                 Value = i.Value,
                                                 Selected = (selectedValues != null && selectedValues.Contains(i.Value))
                                             };
  
            return CheckBoxList(helper, name, selectListItems, checkboxHtmlAttributes);
        }
  
        public static string CheckBoxList(this HtmlHelper helper, string name, IEnumerable<SelectListItem> items)
        {
            return CheckBoxList(helper, name, items, null);
        }
  
        public static string CheckBoxList(this HtmlHelper helper, string name, IEnumerable<SelectListItem> items, IDictionary<string, object> checkboxHtmlAttributes)
        {
            var output = new StringBuilder();
  
            foreach (var item in items)
            {
                output.Append(&ldquo;&ldquo;);
                var checkboxList = new TagBuilder("input&rdquo;);
                checkboxList.MergeAttribute(&ldquo;type&rdquo;, &ldquo;checkbox&rdquo;);
                checkboxList.MergeAttribute(&ldquo;name&rdquo;, name);
                checkboxList.MergeAttribute(&ldquo;value&rdquo;, item.Value);
  
                // Check to see if it&rsquo;s checked
                if (item.Selected)
                    checkboxList.MergeAttribute(&ldquo;checked&rdquo;, &ldquo;checked&rdquo;);
  
                // Add any attributes
                if (checkboxHtmlAttributes != null)
                    checkboxList.MergeAttributes(checkboxHtmlAttributes);
  
                checkboxList.SetInnerText(item.Text);
                output.Append(checkboxList.ToString(TagRenderMode.SelfClosing));
                output.Append(&ldquo;  &rdquo; + item.Text + &ldquo;&rdquo;);
            }
  
            return output.ToString();
        }
    }
}

On the view you can pass a dictionary made from items in your view model and selected values form your view model.

<div>
    ${Html.CheckBoxList(&ldquo;Product.Categories&rdquo;,
      ViewData.Model.Categories.ToDictionary(c => c.Name, c => c.Id.ToString()),
      ViewData.Model.Product.Categories.Select(c => c.Id.ToString()))}
</div>

In the controller you can access the form values in the request as a comma list of values by the name of the form field.

Request.Form["Product.Categories"]

Hope this helps and thanks to Tyler Garlick for meat of the code.

[UPDATE] Tyler has updated is code for MVC 2.0, here.