Quelqu’un at-il implémenté RadioButtonListFor pour ASP.NET MVC?

Il y avait une méthode d’extension Html.RadioButtonList dans ASP.NET MVC Futures. Quelqu’un at-il trouvé un code pour une version fortement typée RadioButtonListFor . Cela ressemblerait à ceci dans une vue:

 model.Item,Model.ItemList) %> 

Voici l’utilisation dans la page aspx

  <%= Html.RadioButtonListFor(m => m.GenderRadioButtonList)%> 

Voici le modèle de vue

 public class HomePageViewModel { public enum GenderType { Male, Female } public RadioButtonListViewModel GenderRadioButtonList { get; set; } public HomePageViewModel() { GenderRadioButtonList = new RadioButtonListViewModel { Id = "Gender", SelectedValue = GenderType.Male, ListItems = new List> { new RadioButtonListItem{Text = "Male", Value = GenderType.Male}, new RadioButtonListItem{Text = "Female", Value = GenderType.Female} } }; } } 

Voici le modèle de vue utilisé pour les listes de boutons radio

 public class RadioButtonListViewModel { public ssortingng Id { get; set; } private T selectedValue; public T SelectedValue { get { return selectedValue; } set { selectedValue = value; UpdatedSelectedItems(); } } private void UpdatedSelectedItems() { if (ListItems == null) return; ListItems.ForEach(li => li.Selected = Equals(li.Value, SelectedValue)); } private List> listItems; public List> ListItems { get { return listItems; } set { listItems = value; UpdatedSelectedItems(); } } } public class RadioButtonListItem { public bool Selected { get; set; } public ssortingng Text { get; set; } public T Value { get; set; } public override ssortingng ToSsortingng() { return Value.ToSsortingng(); } } 

Voici les méthodes d’extension pour RadioButtonListFor

 public static class HtmlHelperExtensions { public static ssortingng RadioButtonListFor(this HtmlHelper htmlHelper, Expression>> expression) where TModel : class { return htmlHelper.RadioButtonListFor(expression, null); } public static ssortingng RadioButtonListFor(this HtmlHelper htmlHelper, Expression>> expression, object htmlAtsortingbutes) where TModel : class { return htmlHelper.RadioButtonListFor(expression, new RouteValueDictionary(htmlAtsortingbutes)); } public static ssortingng RadioButtonListFor(this HtmlHelper htmlHelper, Expression>> expression, IDictionary htmlAtsortingbutes) where TModel : class { var inputName = GetInputName(expression); RadioButtonListViewModel radioButtonList = GetValue(htmlHelper, expression); if (radioButtonList == null) return Ssortingng.Empty; if (radioButtonList.ListItems == null) return Ssortingng.Empty; var divTag = new TagBuilder("div"); divTag.MergeAtsortingbute("id", inputName); divTag.MergeAtsortingbute("class", "radio"); foreach (var item in radioButtonList.ListItems) { var radioButtonTag = RadioButton(htmlHelper, inputName, new SelectListItem{Text=item.Text, Selected = item.Selected, Value = item.Value.ToSsortingng()}, htmlAtsortingbutes); divTag.InnerHtml += radioButtonTag; } return divTag + htmlHelper.ValidationMessage(inputName, "*"); } public static ssortingng GetInputName(Expression> expression) { if (expression.Body.NodeType == ExpressionType.Call) { var methodCallExpression = (MethodCallExpression)expression.Body; ssortingng name = GetInputName(methodCallExpression); return name.Subssortingng(expression.Parameters[0].Name.Length + 1); } return expression.Body.ToSsortingng().Subssortingng(expression.Parameters[0].Name.Length + 1); } private static ssortingng GetInputName(MethodCallExpression expression) { // p => p.Foo.Bar().Baz.ToSsortingng() => p.Foo OR throw... var methodCallExpression = expression.Object as MethodCallExpression; if (methodCallExpression != null) { return GetInputName(methodCallExpression); } return expression.Object.ToSsortingng(); } public static ssortingng RadioButton(this HtmlHelper htmlHelper, ssortingng name, SelectListItem listItem, IDictionary htmlAtsortingbutes) { var inputIdSb = new SsortingngBuilder(); inputIdSb.Append(name) .Append("_") .Append(listItem.Value); var sb = new SsortingngBuilder(); var builder = new TagBuilder("input"); if (listItem.Selected) builder.MergeAtsortingbute("checked", "checked"); builder.MergeAtsortingbute("type", "radio"); builder.MergeAtsortingbute("value", listItem.Value); builder.MergeAtsortingbute("id", inputIdSb.ToSsortingng()); builder.MergeAtsortingbute("name", name + ".SelectedValue"); builder.MergeAtsortingbutes(htmlAtsortingbutes); sb.Append(builder.ToSsortingng(TagRenderMode.SelfClosing)); sb.Append(RadioButtonLabel(inputIdSb.ToSsortingng(), listItem.Text, htmlAtsortingbutes)); sb.Append("
"); return sb.ToSsortingng(); } public static ssortingng RadioButtonLabel(ssortingng inputId, ssortingng displayText, IDictionary htmlAtsortingbutes) { var labelBuilder = new TagBuilder("label"); labelBuilder.MergeAtsortingbute("for", inputId); labelBuilder.MergeAtsortingbutes(htmlAtsortingbutes); labelBuilder.InnerHtml = displayText; return labelBuilder.ToSsortingng(TagRenderMode.Normal); } public static TProperty GetValue(HtmlHelper htmlHelper, Expression> expression) where TModel : class { TModel model = htmlHelper.ViewData.Model; if (model == null) { return default(TProperty); } Func func = expression.Comstack(); return func(model); } }

MVC 3 exemple qui crée 3 boutons radio avec validation pour assurer 1 option est sélectionnée. Et si la validation du formulaire échoue (par exemple sur d’autres champs), l’option de radio choisie est présélectionnée lors de la remise en forme du formulaire.

Vue

 @Html.RadioButtonForSelectList(m => m.TestRadio, Model.TestRadioList) @Html.ValidationMessageFor(m => m.TestRadio) 

Modèle

 public class aTest { public Int32 ID { get; set; } public Ssortingng Name { get; set; } } public class LogOnModel { public IEnumerable TestRadioList { get; set; } [Required(ErrorMessage="Test Error")] public Ssortingng TestRadio { get; set; } [Required] [Display(Name = "User name")] public ssortingng UserName { get; set; } } 

Actions du contrôleur

 public ActionResult LogOn() { List list = new List(); list.Add(new aTest() { ID = 1, Name = "Line1" }); list.Add(new aTest() { ID = 2, Name = "Line2" }); list.Add(new aTest() { ID = 3, Name = "Line3" }); SelectList sl = new SelectList(list, "ID", "Name"); var model = new LogOnModel(); model.TestRadioList = sl; return View(model); } [HttpPost] public ActionResult LogOn(LogOnModel model, ssortingng returnUrl) { if (ModelState.IsValid) { .... } // If we got this far, something failed, redisplay form List list = new List(); list.Add(new aTest() { ID = 1, Name = "Line1" }); list.Add(new aTest() { ID = 2, Name = "Line2" }); list.Add(new aTest() { ID = 3, Name = "Line3" }); SelectList sl = new SelectList(list, "ID", "Name"); model.TestRadioList = sl; return View(model); } 

Voici l’extension:

 public static class HtmlExtensions { public static MvcHtmlSsortingng RadioButtonForSelectList( this HtmlHelper htmlHelper, Expression> expression, IEnumerable listOfValues) { var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); var sb = new SsortingngBuilder(); if (listOfValues != null) { foreach (SelectListItem item in listOfValues) { var id = ssortingng.Format( "{0}_{1}", metaData.PropertyName, item.Value ); var radio = htmlHelper.RadioButtonFor(expression, item.Value, new { id = id }).ToHtmlSsortingng(); sb.AppendFormat( " {2}", id, HttpUtility.HtmlEncode(item.Text), radio ); } } return MvcHtmlSsortingng.Create(sb.ToSsortingng()); } } 

D’accord, je suis conscient que ce n’est pas une réponse directe à votre question, mais cela peut être une meilleure façon de faire la plupart des intrants de toute façon (et c’était amusant à faire). Je viens juste de terminer ce travail et j’ai effectué une petite quantité d’essais, alors je ne peux pas garantir que cela soit parfait dans toutes les situations.

J’ai eu cette idée du post de Jimmy Bogard ici . Jetez un oeil parce qu’il y a un tas d’idées vraiment cool là-bas.

Ce que j’ai fait est de créer un assistant “InputFor” qui essaie de son mieux pour déterminer quelle entrée vous demandez et la reproduit en conséquence. Cela fera des boutons radio, mais par défaut il y aura un menu déroulant s’il y en a plus de deux, vous devriez pouvoir changer cette fonctionnalité assez facilement.

Le code ci-dessous vous permet d’effectuer des appels tels que <%= Html.InputFor(m => m.Gender) %> ou <%Html.InputFor(m => m.Gender, Model.GenderList)%> . Il y a un petit peu sympa à la fin qui vous permet de faire du codage par convention, mais nous y reviendrons plus tard.

 public static MvcHtmlSsortingng InputFor(this HtmlHelper helper, Expression> field, Dictionary listing) where TModel : class { ssortingng property_name = GetInputName(field); PropertyDescriptor descriptor = TypeDescriptor.GetProperties(helper.ViewData.Model).Find(property_name, true); ssortingng property_type = descriptor.PropertyType.Name; var func = field.Comstack(); var value = func(helper.ViewData.Model); //Add hidden element if required if (descriptor.Atsortingbutes.Contains(new HiddenInputAtsortingbute())) { return helper.Hidden(property_name, value); } if (property_type == "DateTime" || property_type == "Date") { return helper.TextBox(property_name, value, new { @class = "date_picker" }); } if (listing != null) { if (listing.Count <= 2) { //This is a good length for a radio button string output = ""; foreach (KeyValuePair pair in listing) { TagBuilder label = new TagBuilder("label"); label.MergeAtsortingbute("for", property_name); label.SetInnerText(pair.Value); output += helper.RadioButton(property_name, pair.Key, (value == pair.Key)).ToHtmlSsortingng(); output += label.ToSsortingng(); } return MvcHtmlSsortingng.Create(output); } else { //too big for a radio button, lets make a drop down return helper.DropDownList(property_name, new SelectList(listing, "Key", "Value"), value); } } else { if (property_type == "Boolean") { listing = new Dictionary(); listing.Add("true", "Yes"); listing.Add("false", "No"); SelectList select_values = new SelectList(listing, "Key", "Value", ((bool)value ? "Yes" : "No")); return helper.DropDownList(property_name, select_values); } return helper.TextBox(property_name, value); } } 

Codage par convention

Le code ci-dessous permet de le faire avec la convention sur la configuration en tête. Un exemple de ceci est que si vous avez un object modèle qui contient la propriété que vous voulez lister (Gender) et un dictionnaire avec le même nom mais ajouté avec “List” (GenderList) alors il utilisera cette liste par défaut.

Par exemple, <%= Html.InputFor(m => m.Gender) %> peut créer un groupe complet de listes déroulantes / boutons radio, mais ces valeurs par défaut peuvent être remplacées par un appel comme <%= Html.InputFor(m => m.Gender, alternate_list) %>

 public static MvcHtmlSsortingng InputFor(this HtmlHelper helper, Expression> field) where TModel : class { ssortingng property_name = GetInputName(field) + "List"; PropertyDescriptor list_descriptor = TypeDescriptor.GetProperties(helper.ViewData.Model).Find(property_name, true); Dictionary listing = null; if (list_descriptor != null) { //Found a match for PropertyNameList, try to pull it out so we can use it PropertyInfo temp = helper.ViewData.Model.GetType().GetProperty(property_name); listing = (Dictionary)temp.GetValue(helper.ViewData.Model, null); } return InputFor(helper, field, listing); } 

Maintenant, un léger avertissement:

  • Ce n’est pas le code le plus rapide du monde (à cause de la reflection et d’autres choses), dans ma situation, ce n’est pas vraiment pertinent car tout est piloté par l’utilisateur, si vous avez l’intention de faire quelque chose de stupide.
  • Ce code en est à ses balbutiements, je le testerai plus en détail et je l’appendai au cours des prochains jours, ouvert à toute suggestion visant à améliorer le code.

J’espère que ce code est utile à quelqu’un, je sais que je vais l’utiliser au cours des prochaines semaines pour essayer de réduire le temps. Couper ceci pour faire juste le bouton radio devrait être une tâche sortingviale, bonne chance 🙂

Geai

Basé à Jon post , une petite amélioration pour générer la liste des boutons radio ul avec HTMLAtsortingbuttes

 public static MvcHtmlSsortingng RadioButtonListFor( this HtmlHelper htmlHelper, Expression> expression, IEnumerable listOfValues, IDictionary radioHtmlAtsortingbutes = null, ssortingng ulClass = null) { ModelMetadata metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); if (radioHtmlAtsortingbutes == null) radioHtmlAtsortingbutes = new RouteValueDictionary(); TagBuilder ulTag = new TagBuilder("ul"); if (!Ssortingng.IsNullOrEmpty(ulClass)) ulTag.MergeAtsortingbute("class", ulClass); if (listOfValues != null) { // Create a radio button for each item in the list foreach (SelectListItem item in listOfValues) { // Generate an id to be given to the radio button field var id = ssortingng.Format("{0}_{1}", metaData.PropertyName, item.Value); if (!radioHtmlAtsortingbutes.ContainsKey("id")) radioHtmlAtsortingbutes.Add("id", id); else radioHtmlAtsortingbutes["id"] = id; // Create and populate a radio button using the existing html helpers var label = htmlHelper.Label(id, HttpUtility.HtmlEncode(item.Text)); var radio = htmlHelper.RadioButtonFor(expression, item.Value, radioHtmlAtsortingbutes).ToHtmlSsortingng(); // Create the html ssortingng that will be returned to the client // eg  ulTag.InnerHtml += ssortingng.Format("
  • {0}{1}
  • ", radio, label); } } return MvcHtmlSsortingng.Create(ulTag.ToSsortingng(TagRenderMode.Normal)); } public static MvcHtmlSsortingng RadioButtonListFor( this HtmlHelper htmlHelper, Expression> expression, IEnumerable listOfValues, object radioHtmlAtsortingbutes = null, ssortingng ulClass = null) { return RadioButtonListFor(htmlHelper, expression, listOfValues, new RouteValueDictionary(radioHtmlAtsortingbutes), ulClass); }

    J’ai implémenté quelque chose de similaire dans MVC 1.0. Voyez si cela vous sera utile:

      public static ssortingng RadioButtonList2(this HtmlHelper _helper, ssortingng _name, IEnumerable _items, ssortingng _selectedValue, ssortingng _seperator) { return RadioButtonList2(_helper, _name, _items, _selectedValue, _seperator, null); } public static ssortingng RadioButtonList2(this HtmlHelper _helper, ssortingng _name, IEnumerable _items, ssortingng _selectedValue, ssortingng _seperator, IDictionary _htmlAtsortingbutes) { SsortingngBuilder _outputScript = new SsortingngBuilder(); foreach (var item in _items) { var optionField = new TagBuilder("input"); optionField.MergeAtsortingbute("name", _name); optionField.MergeAtsortingbute("id", _name); optionField.MergeAtsortingbute("class", _name); optionField.MergeAtsortingbute("value", item.Value); optionField.MergeAtsortingbute("type", "radio"); // Check to see if it's checked if (item.Value == _selectedValue) optionField.MergeAtsortingbute("checked", "checked"); if (_htmlAtsortingbutes != null) optionField.MergeAtsortingbutes(_htmlAtsortingbutes); _outputScript.Append(optionField.ToSsortingng(TagRenderMode.SelfClosing)); _outputScript.Append("" + _seperator); } return _outputScript.ToSsortingng(); } 

    Dans le contrôleur, vous pouvez retourner le résultat comme suit:

      ViewData["GenderList"] = new SelectList(new[] { new { Value = "M", Text = "Male" }, new { Value = "F", Text = "Female" }, new { Value = "A", Text = "All" } }, "Value", "Text"); 

    ou

      ViewData["GenderList"] = new SelectList(_resultFromSomeLinqQuery, "GenderID", "GenderName"); 

    Et l’utiliser dans la vue comme suit:

     <%= Html.RadioButtonList2("Sex", ViewData["GenderList"] as SelectList, ViewData["SelectedSex"].ToString(), " ")%> 

    Vous pouvez également remplacer le   avec
    pour les afficher en lignes séparées.

    J’espère que cela t’aides.

    Cordialement Naweed Akram [email protected]

    Voici une réponse légèrement plus «mince» en bon vieux VB. Fonctionne pour moi, mais ce n’est pas une solution complète.

      _ Public Function RadioButtonListFor(Of TModel, TProperty)(ByVal htmlHelper As System.Web.Mvc.HtmlHelper(Of TModel), ByVal expression As System.Linq.Expressions.Expression(Of System.Func(Of TModel, TProperty)), ByVal selectList As System.Collections.Generic.IEnumerable(Of System.Web.Mvc.SelectListItem), ByVal htmlAtsortingbutes As Object) As System.Web.Mvc.MvcHtmlSsortingng 'Return htmlHelper.DropDownListFor(expression, selectList, htmlAtsortingbutes) If selectList Is Nothing OrElse selectList.Count = 0 Then Return MvcHtmlSsortingng.Empty Dim divTag = New TagBuilder("div") divTag.MergeAtsortingbutes(New RouteValueDictionary(htmlAtsortingbutes)) Dim name = CType(expression.Body, System.Linq.Expressions.MemberExpression).Member.Name Dim value = expression.Comstack()(htmlHelper.ViewData.Model) Dim sb As New SsortingngBuilder() For Each item In selectList sb.AppendFormat("", name, item.Value, If(item.Value = value.ToSsortingng, """checked""", "")) sb.AppendFormat("", name, item.Value, item.Text) Next divTag.InnerHtml = sb.ToSsortingng Return MvcHtmlSsortingng.Create(divTag.ToSsortingng) End Function 

    J’ai modifié la solution de Mac et remplacé le type Enum par la table de firebase database, ma table est la suivante:

    entrer la description de l'image ici

    Dans ma candidature, je loue une salle en fonction des préférences de genre. Mon modèle avec la propriété GenderRadios:

     public partial class Room { public RadioButtonListViewModel GenderRadios { get; set; } //... } 

    Dans le contrôleur de pièce, je prépare des radios:

      private void fillRadios(Room room) { List genders = fre.Genders.ToList(); room.GenderRadios= new RadioButtonListViewModel(); room.GenderRadios.ListItems = new List(); foreach (Gender gender in genders) room.GenderRadios.ListItems.Add(new RadioButtonListItem { Text = gender.Name, Value = gender.Id, Selected= (room.GenderId == gender.Id)}); } 

    enfin, je l’utilise dans la vue pour créer de la place:

      Gender <%= Html.RadioButtonListFor(m => m.GenderRadios, "GenderRadiosForRoomCreate")%>  

    et pour la salle de assembly:

      Gender <%= Html.RadioButtonListFor(m => m.GenderRadios, "GenderRadiosForRoomEdit")%>  

    Créer une salle HTML ressemblera à:

          

    Lorsque la pièce a été créée:

     [HttpPost] public ActionResult RoomCreate(Room room, FormCollection formValues, int? GenderRadiosForRoomCreate_value, int? SmokingRadiosForRoomCreate_value) { room.GenderId = GenderRadiosForRoomCreate_value; room.SmokingId = SmokingRadiosForRoomCreate_value; //... } 

    Voici la classe des assistants:

     public class RadioButtonListViewModel { public int Id { get; set; } private int selectedValue; public int SelectedValue { get { return selectedValue; } set { selectedValue = value; UpdatedSelectedItems(); } } private void UpdatedSelectedItems() { if (ListItems == null) return; ListItems.ForEach(li => li.Selected = Equals(li.Value, SelectedValue)); } private List listItems; public List ListItems { get { return listItems; } set { listItems = value; UpdatedSelectedItems(); } } } public class RadioButtonListItem { public bool Selected { get; set; } public ssortingng Text { get; set; } public int Value { get; set; } public override ssortingng ToSsortingng() { return Value.ToSsortingng(); } } public static class HtmlHelperExtensions { /* tagBase: I used tagBase ssortingng for building other tag's Id or Name on this. ie for tagBase="GenderRadiosForRoomCreate"      */ public static ssortingng RadioButtonListFor(this HtmlHelper htmlHelper, Expression> expression, Ssortingng tagBase) where TModel : class { return htmlHelper.RadioButtonListFor(expression, tagBase, null); } public static ssortingng RadioButtonListFor(this HtmlHelper htmlHelper, Expression> expression, Ssortingng tagBase, object htmlAtsortingbutes) where TModel : class { return htmlHelper.RadioButtonListFor(expression, tagBase, new RouteValueDictionary(htmlAtsortingbutes)); } public static ssortingng RadioButtonListFor(this HtmlHelper htmlHelper, Expression> expression, Ssortingng tagBase, IDictionary htmlAtsortingbutes) where TModel : class { var inputName = tagBase; RadioButtonListViewModel radioButtonList = GetValue(htmlHelper, expression); if (radioButtonList == null) return Ssortingng.Empty; if (radioButtonList.ListItems == null) return Ssortingng.Empty; var containerTag = new TagBuilder("td"); containerTag.MergeAtsortingbute("id", inputName + "_Container"); foreach (var item in radioButtonList.ListItems) { var radioButtonTag = RadioButton(htmlHelper, inputName, new SelectListItem{Text=item.Text, Selected = item.Selected, Value = item.Value.ToSsortingng()}, htmlAtsortingbutes); containerTag.InnerHtml += radioButtonTag; } return containerTag.ToSsortingng(); } public static ssortingng RadioButton(this HtmlHelper htmlHelper, ssortingng name, SelectListItem listItem, IDictionary htmlAtsortingbutes) { var inputIdSb = new SsortingngBuilder(); inputIdSb.Append(name); var sb = new SsortingngBuilder(); var builder = new TagBuilder("input"); if (listItem.Selected) builder.MergeAtsortingbute("checked", "checked"); builder.MergeAtsortingbute("type", "radio"); builder.MergeAtsortingbute("value", listItem.Value); builder.MergeAtsortingbute("id", inputIdSb.ToSsortingng() + "_" + listItem.Text); builder.MergeAtsortingbute("name", name + "_value"); builder.MergeAtsortingbutes(htmlAtsortingbutes); sb.Append(builder.ToSsortingng(TagRenderMode.SelfClosing)); sb.Append(RadioButtonLabel(inputIdSb.ToSsortingng(), listItem.Text, htmlAtsortingbutes)); return sb.ToSsortingng(); } public static ssortingng RadioButtonLabel(ssortingng inputId, ssortingng displayText, IDictionary htmlAtsortingbutes) { var labelBuilder = new TagBuilder("label"); labelBuilder.MergeAtsortingbute("for", inputId + "_" + displayText); labelBuilder.MergeAtsortingbutes(htmlAtsortingbutes); labelBuilder.InnerHtml = displayText; return labelBuilder.ToSsortingng(TagRenderMode.Normal); } public static TProperty GetValue(HtmlHelper htmlHelper, Expression> expression) where TModel : class { TModel model = htmlHelper.ViewData.Model; if (model == null) { return default(TProperty); } Func func = expression.Comstack(); return func(model); } }