2010-10-08 40 views
15

Tôi biết có một phương pháp mở rộng ListBoxFor trong số các phương pháp mở rộng trình trợ giúp ASP.NET MVC Html, nhưng tôi luôn nghĩ rằng danh sách hộp kiểm thân thiện với người dùng hơn hộp danh sách.Cách tạo phương thức mở rộng CheckBoxListFor trong ASP.NET MVC?

Có một điều khiển rất thuận tiện CheckBoxList trong các WebForms cũ tốt, nhưng rõ ràng là đã hết hình ảnh ngay bây giờ.

Câu hỏi đặt ra là, tại sao không có cách nào trong ASP.NET MVC để tạo danh sách hộp kiểm? Làm thế nào tôi có thể viết phương pháp mở rộng của riêng tôi tạo danh sách hộp kiểm và hoạt động theo cách tương tự ListBoxFor hoạt động?

Trả lời

33

Đây là một HtmlHelper được nhập mạnh mẽ cho CheckBoxListFor xử lý các mục đã chọn dưới dạng mảng trong mô hình chế độ xem của bạn. Tôi đã chọn không bao bọc các phương thức Html.CheckBox hoặc Html.CheckBoxFor vì tôi không muốn các trường "sai" bị ẩn trong danh sách hộp kiểm của mình.

Xin vui lòng để cải thiện về vấn đề này và repost :-)

//View 

<%: Html.CheckBoxListFor(model => model.FreightTypeIds, FreightTypeMultiSelectList) %> 

//Controller 

    public ActionResult SomeAction(int[] FreightTypeIds) 
    { 
     //... 

     return View(); 
    } 


//Extension 
public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, IEnumerable<TProperty>>> expression, MultiSelectList allOptions, object htmlAttributes = null) 
{ 
    ModelMetadata modelMetadata = ModelMetadata.FromLambdaExpression<TModel, IEnumerable<TProperty>>(expression, htmlHelper.ViewData); 

    // Derive property name for checkbox name 
    string propertyName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(modelMetadata.PropertyName); 

    // Get currently select values from the ViewData model 
    IEnumerable<TProperty> list = expression.Compile().Invoke(htmlHelper.ViewData.Model); 

    // Convert selected value list to a List<string> for easy manipulation 
    IList<string> selectedValues = new List<string>(); 

    if (list != null) 
    { 
     selectedValues = new List<TProperty>(list).ConvertAll<string>(delegate(TProperty i) { return i.ToString(); }); 
    } 

    // Create div 
    TagBuilder divTag = new TagBuilder("div"); 
    divTag.MergeAttributes(new RouteValueDictionary(htmlAttributes), true); 

    // Add checkboxes 
    foreach (SelectListItem item in allOptions) 
    { 
     divTag.InnerHtml += string.Format(
              "<div><input type=\"checkbox\" name=\"{0}\" id=\"{1}_{2}\" " + 
              "value=\"{2}\" {3} /><label for=\"{1}_{2}\">{4}</label></div>", 
              propertyName, 
              TagBuilder.CreateSanitizedId(propertyName), 
              item.Value, 
              selectedValues.Contains(item.Value) ? "checked=\"checked\"" : string.Empty, 
              item.Text); 
    } 

    return MvcHtmlString.Create(divTag.ToString()); 
} 
+0

cảm ơn, điều này có vẻ là những gì tôi đang tìm kiếm. Sẽ thử nó một khi tôi về nhà. – Venemo

+1

Với một số sửa đổi, tôi đã thực hiện thành công nó để hoạt động như tôi muốn. Cảm ơn bạn rất nhiều vì mã! :) – Venemo

+0

Tôi thích điều này! Tôi chỉ tự hỏi làm thế nào để thực hiện xác nhận (không phô trương) bây giờ ... –

0

Bạn có thể quan tâm đến CheckBoxList Helper for MVC bài viết của Jeremiah Clark (tiếc là ngày tháng 11 năm 2008 và mối quan tâm MVC 1).

+0

bài viết này là tốt, nhưng nó không được viết bằng HTML gõ mạnh người giúp đỡ trong tâm trí. – Venemo

1

Trong khi nhân viên của Microsoft có lẽ là những người duy nhất có thể trả lời tại sao phương pháp helper như không tồn tại, bạn có thể thử:

mẫu:

public class MyViewModel 
{ 
    public bool[] Values { get; set; } 
} 

Bộ điều khiển:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new MyViewModel 
     { 
      Values = new[] { true, false, true, false } 
     }); 
    } 

    [HttpPost] 
    public ActionResult Index(MyViewModel model) 
    { 
     return View(model); 
    } 
} 

Xem :

<% using (Html.BeginForm()) { %> 
    <%: Html.EditorFor(x => x.Values) %> 
    <input type="submit" value="OK" /> 
<% } %> 

Như bạn có thể thấy EditorFor sẽ xử lý mọi thứ cần thiết.

+0

Đây là một ý tưởng hay, nhưng như tôi đã nói, tôi muốn có một cái gì đó tương tự như hành vi của 'ListBoxFor'. – Venemo

+0

Bạn có thể cụ thể hơn một chút không? 'ListBoxFor' tạo'