2010-09-17 32 views
22

Tôi biết những người khác đã hỏi câu hỏi này, nhưng tôi hoàn toàn nhầm lẫn của thành viên này:ASP.NET MVC MultiSelectList với giá trị được chọn không chọn đúng

này hiển thị danh sách thả xuống không có giá trị được chọn:

<%= Html.DropDownList("items", new MultiSelectList(Model.AvailableItems, 
    "id", "name", Model.items), new { multiple = "multiple" })%> 

này hiển thị danh sách thả xuống với các giá trị mà tôi đang đi qua trong (Model.items) chọn đúng như những gì tôi mong đợi:

<%= Html.DropDownList("somethingelse", new MultiSelectList(Model.AvailableItems, 
    "id", "name", Model.items), new { multiple = "multiple" })%> 

Nhưng vấn đề là mặt hàng này hiện nay được đặt tên "một số thingelse "khi tôi POST. Tôi biết tôi có thể hack xung quanh điều này nhưng những gì đang xảy ra?

+1

Thay vì đặt nhiều trên Html .DropDownList, bạn có thể sử dụng Html.ListBoxFor. Vì Html.DropDownList sẽ chỉ thiết lập một trong các mục được chọn. –

+0

@NikitaIgnatov Cảm ơn. bình luận của bạn thực sự giúp tôi rất nhiều. – gfan

Trả lời

18

Sự cố bạn đang sử dụng Model.Items làm thông số. Mã số

<%= Html.DropDownList("items", new MultiSelectList(Model.AvailableItems, 
    "id", "name", Model.items), new { multiple = "multiple" })%> 

không thực sự hoạt động như bạn mong đợi. Nó hoạt động vì tên của danh sách thả xuống là "các mục". Đó là vì có một tham số biểu mẫu được gọi là "các mục" được đăng lại cho hành động của bạn. Thông số đó được lưu trữ trong ViewState của hành động (đừng nhầm lẫn với ViewData). Html.DropdownList() thấy rằng có một tham số ViewState được đặt tên giống như bạn đã đặt tên cho trình đơn thả xuống của bạn và sử dụng tham số ViewState đó để tính toán các giá trị đã chọn. Nó hoàn toàn bỏ qua Model.items mà bạn đã nhập.

Nếu bất cứ ai có thể giải thích lý do không thể ghi đè hành vi mặc định thì tôi rất muốn nghe nó.

Vì vậy, đó là vấn đề đầu tiên của bạn. Để có được xung quanh tất cả những gì bạn phải làm là đổi tên danh sách thả xuống thành một thứ khác - chính xác như bạn đã làm trong ví dụ thứ hai của mình. Bây giờ vấn đề thứ hai của bạn đi vào chơi: danh sách các mục được chọn phải là một tập hợp các đối tượng đơn giản (tôi nghĩ rằng nó thực sự cần phải là một IEnumerable nhưng tôi không chắc chắn 100%).

Phương thức DropDownList() sẽ thử và khớp các giá trị đã chọn đó với Giá trị trong bộ sưu tập AvailableItems của bạn. Nếu nó không thể làm điều đó nó sẽ cố gắng để phù hợp với văn bản.

Vì vậy, hãy thử này để xem nếu nó hoạt động

<%= Html.DropDownList("somethingelse", new MultiSelectList(Model.AvailableItems, 
    "id", "name", Model.items.Select(c=> c.name)), new { multiple = "multiple" })%> 

Chúc may mắn

+3

Điều này không hoạt động nếu bạn đã chọn nhiều mục. Nó đơn giản chọn đầu tiên bạn đã chọn và bỏ qua phần còn lại. Xem câu trả lời của Darin. – Castrohenge

+0

CUỐI CÙNG một giải pháp làm việc! tôi mất tất cả buổi sáng của tôi trên crap này, cảm ơn;) –

47

bối cảnh Quá ít được cung cấp trong câu hỏi của bạn nhưng tôi sẽ cố gắng để hiển thị một ví dụ làm việc đầy đủ:

mẫu:

public class Item 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

public class MyModel 
{ 
    public IEnumerable<int> SelectedItemIds { get; set; } 
    public IEnumerable<Item> AvailableItems { 
     get 
     { 
      return new[] 
      { 
       new Item { Id = 1, Name = "Item 1" }, 
       new Item { Id = 2, Name = "Item 2" }, 
       new Item { Id = 3, Name = "Item 3" }, 
      }; 
     } 
    } 
} 

Bộ điều khiển:

[HandleError] 
public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var model = new MyModel 
     { 
      SelectedItemIds = new[] { 2, 3 } 
     }; 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult Index(IEnumerable<int> selectedItemIds) 
    { 
     var model = new MyModel 
     { 
      // Important: Don't ever try to modify the selectedItemIds here 
      // The Html helper will completely ignore it and use 
      // the POSTed values 
      SelectedItemIds = selectedItemIds 
     }; 
     return View(model); 
    } 
} 

Xem:

<% using (Html.BeginForm()) { %> 
    <%= Html.ListBoxFor(x => x.SelectedItemIds, 
     new MultiSelectList(Model.AvailableItems, "Id", "Name")) %> 
    <input type="submit" value="GO" /> 
<% } %> 

Lưu ý rằng Html.ListBoxFor được điều chỉnh nhiều hơn nếu bạn muốn tạo nhiều lựa chọn. Rõ ràng là tài sản AvailableItems nên được lấy từ một kho lưu trữ.

+0

Darin Dimitrov cảm ơn tất cả các bạn đã giúp .. Bạn ở khắp mọi nơi .. :) – yusuf

+0

Câu trả lời chất lượng. – radbyx

+0

Có điều gì đó có thể thay đổi trong MVC5 vì câu trả lời chính xác này không hoạt động nữa. – YesMan85

5

tôi đã cùng một vấn đề, tôi đã sử dụng phương pháp gia hạn của riêng tôi để tạo ra html và vấn đề giải quyết

public static MvcHtmlString ListBoxMultiSelectFor<TModel, TProperty>(
     this HtmlHelper<TModel> helper, 
     Expression<Func<TModel, TProperty>> expression, 
     IEnumerable<SelectListItem> selectList, 
     object htmlAttributes) 
    { 
     return ListBoxMultiSelectFor(helper, expression, selectList, new RouteValueDictionary(htmlAttributes)); 
    } 

    public static MvcHtmlString ListBoxMultiSelectFor<TModel, TProperty>(
     this HtmlHelper<TModel> helper, 
     Expression<Func<TModel, TProperty>> expression, 
     IEnumerable<SelectListItem> selectList, 
     IDictionary<string, object> htmlAttributes) 
    { 
     string name = ExpressionHelper.GetExpressionText(expression); 

     TagBuilder selectTag = new TagBuilder("select"); 
     selectTag.MergeAttributes(htmlAttributes); 
     selectTag.MergeAttribute("id", name, true); 
     selectTag.MergeAttribute("name", name, true); 
     foreach (SelectListItem item in selectList) 
     { 
      TagBuilder optionTag = new TagBuilder("option"); 
      optionTag.MergeAttribute("value", item.Value); 
      if (item.Selected) optionTag.MergeAttribute("selected", "selected"); 
      optionTag.InnerHtml = item.Text; 
      selectTag.InnerHtml += optionTag.ToString(); 
     } 

     return new MvcHtmlString(selectTag.ToString()); 
    } 
3

Trên thực tế, nếu bạn nhìn vào mã nguồn MVC hành vi này được nướng vào DropDownListFor theo mặc định (tìm kiếm allowMultiple: false). Các giải pháp là sử dụng ListBoxFor thay vì (bạn sẽ thấy rằng cũng trong mã nguồn MVC, allowMultiple: true), mà làm cho rất nhiều ý nghĩa dưới dạng HTML khôn ngoan, cả hai trả cho

<select ...> 
    <option ...> 
    <option ...> 
    ... 
</select> 

Bạn không cần phải sử dụng các thuộc tính khác nhau trên mô hình như đề xuất trong các câu trả lời ở trên thế này, tôi đã làm việc này bằng cách đơn giản chuyển sang ListBoxFor thay vì (CSS mất nó từ đó):

@Html.ListBoxFor(model => model.SelectedCategories, 
    new MultiSelectList(Model.Categories, Model.SelectedCategories), 
    new { multiple = "multiple" }) 

trình như một say mê, ngay cả với POST và hiển thị lại chế độ xem do lỗi.

0

Bạn có thể đi đến với giá trị của "mặt hàng" với điều này

<HttpPost()> _ 
    Function Edit(ByVal crm_cliente As crm_cliente, ByVal form As FormCollection) As ActionResult 
     If ModelState.IsValid Then 
      Dim items As String 
      crm_cliente.usuario_modifico = "ejmorales" 
      crm_cliente.fecha_modifico = Date.Now 
      items = form("items") 

đó sẽ giúp bạn có được các mục đã chọn như là một chuỗi riêng biệt bằng dấu phẩy (,)

Các vấn đề liên quan