我想获得一些选项(比如付款方式现金,信用卡等)并将这些选项绑定到单选按钮。我相信MVC 3中没有RadioButtonList。
此外,一旦绑定了无线电,我想在编辑答案时向用户显示以前选择的选项。
答案 0 :(得分:37)
与往常一样,您要从模型开始:
public enum PaiementMethod
{
Cash,
CreditCard,
}
public class MyViewModel
{
public PaiementMethod PaiementMethod { get; set; }
}
然后是控制器:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel();
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
}
最后一个观点:
@model MyViewModel
@using (Html.BeginForm())
{
<label for="paiement_cash">Cash</label>
@Html.RadioButtonFor(x => x.PaiementMethod, "Cash", new { id = "paiement_cash" })
<label for="paiement_cc">Credit card</label>
@Html.RadioButtonFor(x => x.PaiementMethod, "CreditCard", new { id = "paiement_cc" })
<input type="submit" value="OK" />
}
如果您想要一些更通用的解决方案,将其封装在帮助器中,您可能会发现following answer很有帮助。
答案 1 :(得分:4)
这就是我喜欢绑定RadioButtonLists的方式。视图模型包含我的强类型对象的集合。例如,也许PaymentOptions是代码表。除了集合之外还有SelectedPaymentOptionKey(如果您的主键前缀为Id,则为Selected * Id)。最初这个键只是默认值0,但在回发时,它将保留所选项的值。
public class PaymentSelectionVM
{
public ICollection<PaymentOption> PaymentOptions { get; set; }
public int SelectedPaymentOptionKey { get; set; }
}
public ViewResult PaymentSelection()
{
var paymentOptions = db.PaymentOptions.ToList();
return View(
new PaymentSelectionVM {
PaymentOptions = paymentOptions,
//This is not required, but shows how to default the selected radiobutton
//Perhaps you have a relationship between a Customer and PaymentOption already,
//SelectedPaymentOptionKey = someCustomer.LastPaymentOptionUsed.PaymentOptionKey
// or maybe just grab the first one(note this would NullReferenceException on empty collection)
//SelectedPaymentOptionKey = paymentOptions.FirstOrDefault().PaymentOptionKey
});
}
然后在视图中:
@foreach (var opt in Model.PaymentOptions)
{
@*Any other HTML here that you want for displaying labels or styling*@
@Html.RadioButtonFor(m => m.SelectedPaymentOptionKey, opt.PaymentOptionKey)
}
m.SelectedPaymentOptionKey有两个目的。首先,它将单选按钮组合在一起,以便选择是互斥的(我鼓励你使用像FireBug这样的东西来检查生成的html只是为了你自己的理解。关于MVC的好处是生成的HTML是相当基本和标准的所以你最终能够预测你的观点的行为并不困难。这里几乎没有什么魔力。)其次,它将在回发中保留所选项目的值。
最后在post处理程序中,我们有了SelectedPaymentOptionKey:
[HttpPost]
public ActionResult PaymentSelection(PaymentSelectionVM vm)
{
currentOrder.PaymentOption = db.PaymentOptions.Find(vm.SelectedPaymentOptionKey);
....
}
与使用SelectListItems相比,这样做的好处是,在显示网格/表并需要显示对象的多个值的情况下,您可以访问更多对象的属性。我也喜欢Html助手中没有像其他方法那样传递硬编码字符串。
缺点是你得到的单选按钮都具有相同的ID,这不是一个好习惯。通过更改为:
可以轻松解决此问题 @Html.RadioButtonFor(m => m.SelectedPaymentOptionKey, opt.PaymentOptionKey, new { id = "PaymentOptions_" + opt.PaymentOptionKey})
最后,对于我见过的大多数单选按钮技术,验证有点古怪。如果我真的需要它,我会在点击单选按钮时连接一些jquery来填充隐藏的SelectedPaymentOptionsKey,并将[Required]
或其他验证放在隐藏字段上。
验证问题的另一种解决方法 ASP.NET MVC 3 unobtrusive validation and radio buttons
这看起来很有希望,但我没有机会测试它: http://memoriesdotnet.blogspot.com/2011/11/mvc-3-radiobuttonlist-including.html
答案 2 :(得分:0)
您应该将选项绑定到ViewModel中的SelectList,并将Selected属性设置为true以用于先前选择的选项