强类型单选按钮列表

发布于 2024-11-01 05:24:02 字数 114 浏览 7 评论 0原文

我想要一些选项(比如支付方式现金、信用卡等)并将它们绑定到单选按钮。我相信 MVC 3 中没有 RadioButtonList。

此外,一旦绑定了单选按钮,我想在编辑答案时向用户显示之前选择的选项。

I want to get some options (say payment method cash, credit card etc.) and bind these to radio buttons. I believe there is no RadioButtonList in MVC 3.

Also, once radios are bound I want to show the previously selected option to the user while editing the answer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

婴鹅 2024-11-08 05:24:02

与往常一样,您从模型开始:

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" />
}

如果您想要一些更通用的解决方案,将其封装在帮助程序中,您可能会找到 以下答案有帮助。

As always you start with a model:

public enum PaiementMethod
{
    Cash,
    CreditCard,
}

public class MyViewModel
{
    public PaiementMethod PaiementMethod { get; set; }
}

then a controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel();
        return View(model);
    }

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

and finally a view:

@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" />
}

And if you want some more generic solution which encapsulates this in a helper you may find the following answer helpful.

自此以后,行同陌路 2024-11-08 05:24:02

这就是我喜欢绑定 RadioButtonList 的方式。视图模型有我的强类型对象的集合。例如,PaymentOptions 可能是一个代码表。与该集合一起的是 SelectedPaymentOptionKey(或 Selected*Id,如果您在主键上添加 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 是相当基本和标准的因此,您最终能够预测您的视图的行为应该不难,这里没有什么神奇之处。)。其次,它将在回发时保留所选项目的值。

最后,在后处理程序中,我们可以使用 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 不显眼的验证和单选按钮

这看起来很有希望,但我还没有机会测试它:
http://memoriesdotnet.blogspot.com/2011/11/ mvc-3-radiobuttonlist-include.html

This is how I like to bind RadioButtonLists. The view model has a collection of my strongly typed objects. For example, maybe PaymentOptions is a code table. Along with the collection is a SelectedPaymentOptionKey (or Selected*Id if you prefix your primary keys with Id). Initially this key will just be default 0, but on postback, it will hold the value of the selected item.

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 
    });
} 

Then in the View:

@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)
}

The m.SelectedPaymentOptionKey serves two purposes. First, it groups the Radio buttons together so that the selection is mutually exclusive(I would encourage you to use something like FireBug to inspect the generated html just for your own understanding. The wonderful thing about MVC is the generated HTML is fairly basic and standard so it shouldn't be hard for you to eventually be able to predict the behavior of your views. There is very little magic going on here.). Second, it will hold the value of the selected item on postback.

And finally in the post handler we have the SelectedPaymentOptionKey available:

[HttpPost]
public ActionResult PaymentSelection(PaymentSelectionVM vm)
{
   currentOrder.PaymentOption = db.PaymentOptions.Find(vm.SelectedPaymentOptionKey);
   ....
}

The advantage of this over using SelectListItems is you have access to more of the object's properties in the case that you are displaying a grid/table and need to display many values of the object. I also like that there are no hard coded strings being passed in the Html helpers as some other approaches have.

The disadvantage is you get radio buttons which all have the same ID, which is not really a good practice. This is easily fixed by changing to this:

  @Html.RadioButtonFor(m => m.SelectedPaymentOptionKey, opt.PaymentOptionKey, new { id = "PaymentOptions_" + opt.PaymentOptionKey})

Lastly, validation is a bit quirky with most all of the radio button techniques I've seen. If I really needed it, I would wire some jquery up to populate a hidden SelectedPaymentOptionsKey whenever the radio buttons are clicked, and place the [Required] or other validation on the hidden field.

Another workaround for the validation problem
ASP.NET MVC 3 unobtrusive validation and radio buttons

This looks promising but I haven't had a chance to test it:
http://memoriesdotnet.blogspot.com/2011/11/mvc-3-radiobuttonlist-including.html

十年不长 2024-11-08 05:24:02

您应该将选项绑定到 ViewModel 中的 SelectList 并将先前选择的选项的 Selected 属性设置为 true

You should bind your options to SelectList in ViewModel and set Selected attribute to true for previously selected option

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文