2012-10-09 46 views
15

我對ASP.net MVC世界頗爲陌生,我試圖弄清楚如何呈現一組複選框,它們是強類型爲視圖模型。在webforms中,我只是使用checkboxlist控件,但我有點與MVC丟失。我如何使用MVC 4和查看模型呈現一組複選框(強類型)

我正在爲婚禮策劃業務構建一個簡單的聯繫表單,並且需要將用戶選擇的任何複選框值傳遞給我的控制器。

形式複選框需要看起來像這樣: enter image description here

您的幫助將不勝感激。謝謝!

這是我到目前爲止。

控制器

[HttpPost] 
public ActionResult Contact(ContactViewModel ContactVM) 
{ 
    if (!ModelState.IsValid) 
    { 
     return View(ContactVM); 
    } 
    else 
    { 
     //Send email logic 

     return RedirectToAction("ContactConfirm"); 
    } 
} 

視圖模型

public class ContactViewModel 
{ 
    [Required] 
    public string Name { get; set; } 

    [Required] 
    public string Phone { get; set; } 

    [Required] 
    [DataType(DataType.EmailAddress)] 
    public string Email { get; set; } 

    [Required] 
    public string Subject { get; set; } 
    public IEnumerable<SelectListItem> SubjectValues 
    { 
     get 
     { 
      return new[] 
      { 
       new SelectListItem { Value = "General Inquiry", Text = "General Inquiry" }, 
       new SelectListItem { Value = "Full Wedding Package", Text = "Full Wedding Package" }, 
       new SelectListItem { Value = "Day of Wedding", Text = "Day of Wedding" }, 
       new SelectListItem { Value = "Hourly Consultation", Text = "Hourly Consultation" } 
      }; 
     } 
    } 


    //Not sure what I should do for checkboxes... 

} 

VIEW

@model NBP.ViewModels.ContactViewModel 

@{ 
    ViewBag.Title = "Contact"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

@using (Html.BeginForm()) 
{ 
    <div id="ContactContainer"> 
     <div><span class="RequiredField">*&nbsp;</span>Your Name:</div> 
     <div> 
      @Html.TextBoxFor(model => model.Name) 
     </div> 
     <div><span class="RequiredField">*&nbsp;</span>Your Phone:</div> 
     <div> 
      @Html.TextBoxFor(model => model.Phone) 
     </div> 
     <div><span class="RequiredField">*&nbsp;</span>Your Email:</div> 
     <div> 
      @Html.TextBoxFor(model => model.Email) 
     </div> 
     <div>Subject:</div> 
     <div> 
      @Html.DropDownListFor(model => model.Subject, Model.SubjectValues) 
     </div> 
     <div>Vendor Assistance:</div> 
     <div> 

      <!-- CHECKBOXES HERE --> 

     </div> 
     <div> 
      <input id="btnSubmit" type="submit" value="Submit" /> 
     </div> 
    </div> 
} 
+0

我很好奇..你甚至嘗試打字Html.Check ...? –

+1

是的,但我不知道如何將它們與我的視圖模型連接... – Maddhacker24

回答

15

您可以豐富您的視圖模型:

public class VendorAssistanceViewModel 
{ 
    public string Name { get; set; } 
    public bool Checked { get; set; } 
} 

public class ContactViewModel 
{ 
    public ContactViewModel() 
    { 
     VendorAssistances = new[] 
     { 
      new VendorAssistanceViewModel { Name = "DJ/BAND" }, 
      new VendorAssistanceViewModel { Name = "Officiant" }, 
      new VendorAssistanceViewModel { Name = "Florist" }, 
      new VendorAssistanceViewModel { Name = "Photographer" }, 
      new VendorAssistanceViewModel { Name = "Videographer" }, 
      new VendorAssistanceViewModel { Name = "Transportation" }, 
     }.ToList(); 
    } 

    [Required] 
    public string Name { get; set; } 

    [Required] 
    public string Phone { get; set; } 

    [Required] 
    [DataType(DataType.EmailAddress)] 
    public string Email { get; set; } 

    [Required] 
    public string Subject { get; set; } 
    public IEnumerable<SelectListItem> SubjectValues 
    { 
     get 
     { 
      return new[] 
      { 
       new SelectListItem { Value = "General Inquiry", Text = "General Inquiry" }, 
       new SelectListItem { Value = "Full Wedding Package", Text = "Full Wedding Package" }, 
       new SelectListItem { Value = "Day of Wedding", Text = "Day of Wedding" }, 
       new SelectListItem { Value = "Hourly Consultation", Text = "Hourly Consultation" } 
      }; 
     } 
    } 

    public IList<VendorAssistanceViewModel> VendorAssistances { get; set; } 
} 

控制器:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new ContactViewModel()); 
    } 

    [HttpPost] 
    public ActionResult Index(ContactViewModel model) 
    { 
     if (!ModelState.IsValid) 
     { 
      return View(model); 
     } 

     //Send email logic 
     return RedirectToAction("ContactConfirm"); 
    } 
} 

查看:

@using (Html.BeginForm()) 
{ 
    <div id="ContactContainer"> 
     <div><span class="RequiredField">*&nbsp;</span>Your Name:</div> 
     <div> 
      @Html.TextBoxFor(model => model.Name) 
     </div> 
     <div><span class="RequiredField">*&nbsp;</span>Your Phone:</div> 
     <div> 
      @Html.TextBoxFor(model => model.Phone) 
     </div> 
     <div><span class="RequiredField">*&nbsp;</span>Your Email:</div> 
     <div> 
      @Html.TextBoxFor(model => model.Email) 
     </div> 
     <div>Subject:</div> 
     <div> 
      @Html.DropDownListFor(model => model.Subject, Model.SubjectValues) 
     </div> 
     <div>Vendor Assistance:</div> 
     <div> 
      @for (int i = 0; i < Model.VendorAssistances.Count; i++) 
      { 
       <div> 
        @Html.HiddenFor(x => x.VendorAssistances[i].Name) 
        @Html.CheckBoxFor(x => x.VendorAssistances[i].Checked) 
        @Html.LabelFor(x => x.VendorAssistances[i].Checked, Model.VendorAssistances[i].Name) 
       </div> 
      } 
     </div> 
     <div> 
      <input id="btnSubmit" type="submit" value="Submit" /> 
     </div> 
    </div> 
} 
+1

嗨達林,我想我接近,但是當我嘗試從我的控制器訪問選中的字段我沒有得到正確的值。 Im循環使用:foreach(ContactVM.VendorAssistances中的var Vendor)。供應商出現爲NBP.ViewModels.VendorAssistanceViewModel。有什麼想法嗎? – Maddhacker24

+1

那麼,Vendor會以'VendorAssistanceViewModel'出現是很正常的。畢竟'VendorAssistances'屬性被定義爲'IList '。你可以深入一點,看看'Name'和'Checked'屬性:'Vendor.Name'和'Vendor.Checked'。 –

+1

感謝Darin,那就是訣竅。傻我! – Maddhacker24

1

使用您的視圖模型的字符串數組。然後你可以使用我一起入侵的幫手。如果你不想使用助手和枚舉,然後看到底部的實際Html。活頁夾將返回一個字符串數組,其中只有選定的字符串值。如果沒有選中它,它會爲你的數組返回一個空值。你必須考慮的是,你已經被警告:)

視圖模型:

[Display(Name = "Which Credit Cards are Accepted:")] 
     public string[] CreditCards { get; set; } 

助手:

public static HtmlString CheckboxGroup<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> propertySelector, Type EnumType) 
     { 
      var groupName = GetPropertyName(propertySelector); 
      var modelValues = ModelMetadata.FromLambdaExpression(propertySelector, htmlHelper.ViewData).Model;//propertySelector.Compile().Invoke(htmlHelper.ViewData.Model); 
     StringBuilder literal = new StringBuilder(); 

     foreach (var value in Enum.GetValues(EnumType)) 
     { 
      var svalue = value.ToString(); 
      var builder = new TagBuilder("input"); 
      builder.GenerateId(groupName); 
      builder.Attributes.Add("type", "checkbox"); 
      builder.Attributes.Add("name", groupName); 
      builder.Attributes.Add("value", svalue); 
      var contextValues = HttpContext.Current.Request.Form.GetValues(groupName); 
      if ((contextValues != null && contextValues.Contains(svalue)) || (modelValues != null && modelValues.ToString().Contains(svalue))) 
      { 
       builder.Attributes.Add("checked", null); 
      } 

      literal.Append(String.Format("</br>{1}&nbsp;<span>{0}</span>", svalue.Replace('_', ' '),builder.ToString(TagRenderMode.Normal))); 
     } 

     return (HtmlString)htmlHelper.Raw(literal.ToString()); 
    } 

    private static string GetPropertyName<T, TProperty>(Expression<Func<T, TProperty>> propertySelector) 
    { 
     var body = propertySelector.Body.ToString(); 
     var firstIndex = body.IndexOf('.') + 1; 
     return body.Substring(firstIndex); 
    } 

HTML:

@Html.CheckboxGroup(m => m.CreditCards, typeof(VendorCertification.Enums.CreditCardTypes)) 

使用這個命令可以幫助擴展恐慌你:

  <input id="CreditCards" name="CreditCards" type="checkbox" value="Visa" 
      @(Model.CreditCards != null && Model.CreditCards.Contains("Visa") ? "checked=true" : string.Empty)/> 
      &nbsp;<span>Visa</span><br /> 

      <input id="CreditCards" name="CreditCards" type="checkbox" value="MasterCard" 
      @(Model.CreditCards != null && Model.CreditCards.Contains("MasterCard") ? "checked=true" : string.Empty)/> 
      &nbsp;<span>MasterCard</span><br /> 
-2

對我而言,這也是有效的,我認爲這是最簡單的(閱讀以前的答案)。

viewmodel的複選框有一個字符串[]。

public string[] Set { get; set; } 

該視圖具有此代碼,您可以重複輸入多次所需。名稱,輸入控件的id必須與viewmodel的屬性名稱匹配。

<div class="col-md-3"> 
    <div class="panel panel-default panel-srcbox"> 
    <div class="panel-heading"> 
     <h3 class="panel-title">Set</h3> 
    </div> 
    <div class="panel-body"> 
     <div class="form-group-sm"> 
     <label class="control-label col-xs-3">1</label> 
     <div class="col-sm-8"> 
      <input type="checkbox" id="Set" name="Set" value="1" /> 
     </div> 
     <label class="control-label col-xs-3">2</label> 
     <div class="col-sm-8"> 
      <input type="checkbox" id="Set" name="Set" value="2" /> 
     </div> 
     </div> 
    </div> 
    </div> 
</div> 

在post方法上,Set變量是一個數組,具有選中的值(s)。