Quelqu'un a-t-il implémenté RadioButtonList pour ASP.NET MVC?

il y avait une méthode d'extension Html.RadioButtonList dans ASP.NET MVC Futures. Quelqu'un a-t-il trouvé un code pour une version fortement dactylographiée RadioButtonListFor<T> . Il ressemblerait à ceci dans une vue:

<%= Html.RadioButtonListFor(model=>model.Item,Model.ItemList) %>
75
demandé sur Keltex 2010-03-25 05:52:55

7 réponses

Voici l'usage dans la page aspx

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

voici le modèle de la vue

public class HomePageViewModel
{
    public enum GenderType
    {
        Male,
        Female
    }
    public RadioButtonListViewModel<GenderType> GenderRadioButtonList { get; set; }

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

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

public class RadioButtonListViewModel<T>
{
    public string 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<RadioButtonListItem<T>> listItems;
    public List<RadioButtonListItem<T>> ListItems
    {
        get { return listItems; }
        set
        {
            listItems = value;
            UpdatedSelectedItems();
        }
    }
}

public class RadioButtonListItem<T>
{
    public bool Selected { get; set; }

    public string Text { get; set; }

    public T Value { get; set; }

    public override string ToString()
    {
        return Value.ToString();
    }
}

Voici les méthodes d'extension pour RadioButtonListFor

public static class HtmlHelperExtensions
{
    public static string RadioButtonListFor<TModel, TRadioButtonListValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, RadioButtonListViewModel<TRadioButtonListValue>>> expression) where TModel : class
    {
        return htmlHelper.RadioButtonListFor(expression, null);
    }

    public static string RadioButtonListFor<TModel, TRadioButtonListValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, RadioButtonListViewModel<TRadioButtonListValue>>> expression, object htmlAttributes) where TModel : class
    {
        return htmlHelper.RadioButtonListFor(expression, new RouteValueDictionary(htmlAttributes));
    }

    public static string RadioButtonListFor<TModel, TRadioButtonListValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, RadioButtonListViewModel<TRadioButtonListValue>>> expression, IDictionary<string, object> htmlAttributes) where TModel : class
    {
        var inputName = GetInputName(expression);

        RadioButtonListViewModel<TRadioButtonListValue> radioButtonList = GetValue(htmlHelper, expression);

        if (radioButtonList == null)
            return String.Empty;

        if (radioButtonList.ListItems == null)
            return String.Empty;

        var divTag = new TagBuilder("div");
        divTag.MergeAttribute("id", inputName);
        divTag.MergeAttribute("class", "radio");
        foreach (var item in radioButtonList.ListItems)
        {
            var radioButtonTag = RadioButton(htmlHelper, inputName, new SelectListItem{Text=item.Text, Selected = item.Selected, Value = item.Value.ToString()}, htmlAttributes);

            divTag.InnerHtml += radioButtonTag;
        }

        return divTag + htmlHelper.ValidationMessage(inputName, "*");
    }

    public static string GetInputName<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression)
    {
        if (expression.Body.NodeType == ExpressionType.Call)
        {
            var methodCallExpression = (MethodCallExpression)expression.Body;
            string name = GetInputName(methodCallExpression);
            return name.Substring(expression.Parameters[0].Name.Length + 1);

        }
        return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1);
    }

    private static string GetInputName(MethodCallExpression expression)
    {
        // p => p.Foo.Bar().Baz.ToString() => p.Foo OR throw...

        var methodCallExpression = expression.Object as MethodCallExpression;
        if (methodCallExpression != null)
        {
            return GetInputName(methodCallExpression);
        }
        return expression.Object.ToString();
    }

    public static string RadioButton(this HtmlHelper htmlHelper, string name, SelectListItem listItem,
                         IDictionary<string, object> htmlAttributes)
    {
        var inputIdSb = new StringBuilder();
        inputIdSb.Append(name)
            .Append("_")
            .Append(listItem.Value);

        var sb = new StringBuilder();

        var builder = new TagBuilder("input");
        if (listItem.Selected) builder.MergeAttribute("checked", "checked");
        builder.MergeAttribute("type", "radio");
        builder.MergeAttribute("value", listItem.Value);
        builder.MergeAttribute("id", inputIdSb.ToString());
        builder.MergeAttribute("name", name + ".SelectedValue");
        builder.MergeAttributes(htmlAttributes);
        sb.Append(builder.ToString(TagRenderMode.SelfClosing));
        sb.Append(RadioButtonLabel(inputIdSb.ToString(), listItem.Text, htmlAttributes));
        sb.Append("<br>");

        return sb.ToString();
    }

    public static string RadioButtonLabel(string inputId, string displayText,
                                 IDictionary<string, object> htmlAttributes)
    {
        var labelBuilder = new TagBuilder("label");
        labelBuilder.MergeAttribute("for", inputId);
        labelBuilder.MergeAttributes(htmlAttributes);
        labelBuilder.InnerHtml = displayText;

        return labelBuilder.ToString(TagRenderMode.Normal);
    }


    public static TProperty GetValue<TModel, TProperty>(HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) where TModel : class
    {
        TModel model = htmlHelper.ViewData.Model;
        if (model == null)
        {
            return default(TProperty);
        }
        Func<TModel, TProperty> func = expression.Compile();
        return func(model);
    }
}
88
répondu Mac 2011-04-12 23:49:56

MVC 3 Exemple qui crée 3 boutons radio avec validation pour s'assurer que 1 option est sélectionnée. Et si la validation du formulaire échoue (par exemple sur d'autres champs), l'option radio choisie est présélectionnée lorsque le formulaire est refondu.

Vue

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

modèle

public class aTest
{
    public Int32 ID { get; set; }
    public String Name { get; set; }
}

public class LogOnModel
{
    public IEnumerable<SelectListItem> TestRadioList { get; set; }

    [Required(ErrorMessage="Test Error")]
    public String TestRadio { get; set; }

    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }
}

Actions Du Contrôleur

public ActionResult LogOn()
    {
        List<aTest> list = new List<aTest>();
        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, string returnUrl)
    {
        if (ModelState.IsValid)
        {
             ....
        }

        // If we got this far, something failed, redisplay form
        List<aTest> list = new List<aTest>();
        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 MvcHtmlString RadioButtonForSelectList<TModel, TProperty>(
        this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression,
        IEnumerable<SelectListItem> listOfValues)
    {
        var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        var sb = new StringBuilder();

        if (listOfValues != null)
        {
            foreach (SelectListItem item in listOfValues)
            {
                var id = string.Format(
                    "{0}_{1}",
                    metaData.PropertyName,
                    item.Value
                );

                var radio = htmlHelper.RadioButtonFor(expression, item.Value, new { id = id }).ToHtmlString();
                sb.AppendFormat(
                    "<label for=\"{0}\">{1}</label> {2}",
                    id,
                    HttpUtility.HtmlEncode(item.Text),
                    radio
                );
            }
        }

        return MvcHtmlString.Create(sb.ToString());
    }
}
26
répondu Jon 2011-06-07 16:47:23

D'accord, je suis conscient que ce n'est pas une réponse directe à votre question, mais ce pourrait être une meilleure façon de faire la plupart des entrées de toute façon (et c'était amusant à faire). Je viens juste de terminer ceci et j'ai fait quelques tests, donc je ne peux pas garantir que ce soit parfait dans toutes les situations.

J'ai eu cette idée du billet 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 done est créé un helper "InputFor" qui fait de son mieux pour déterminer les entrées que vous demandez et les sorties en conséquence. Cela va faire des boutons radio, mais va par défaut à une chute vers le bas s'il ya plus de deux, vous devriez être en mesure de modifier cette fonctionnalité assez facilement.

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

public static MvcHtmlString InputFor<TModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, object>> field, Dictionary<string, string> listing) where TModel : class
        {
            string property_name = GetInputName(field);
            PropertyDescriptor descriptor = TypeDescriptor.GetProperties(helper.ViewData.Model).Find(property_name, true);
            string property_type = descriptor.PropertyType.Name;
            var func = field.Compile();
            var value = func(helper.ViewData.Model);

            //Add hidden element if required
            if (descriptor.Attributes.Contains(new HiddenInputAttribute()))
            {
                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<string, string> pair in listing)
                    {
                        TagBuilder label = new TagBuilder("label");
                        label.MergeAttribute("for", property_name);
                        label.SetInnerText(pair.Value);
                        output += helper.RadioButton(property_name, pair.Key, (value == pair.Key)).ToHtmlString();
                        output += label.ToString();
                    }
                    return MvcHtmlString.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<string, string>();
                    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 faire ceci avec la convention sur la configuration à l'esprit. Un exemple de ceci est si vous avez un objet model qui contient la propriété que vous voulez lister (genre) 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 faire une liste déroulante/groupe de boutons radio, mais ces les valeurs par défaut peuvent être dépassées en faisant un appel comme <%= Html.InputFor(m => m.Gender, alternate_list) %>

public static MvcHtmlString InputFor<TModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, object>> field) where TModel : class
{
    string property_name = GetInputName(field) + "List";
    PropertyDescriptor list_descriptor = TypeDescriptor.GetProperties(helper.ViewData.Model).Find(property_name, true);
    Dictionary<string, string> 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<string, string>)temp.GetValue(helper.ViewData.Model, null);
    }
    return InputFor(helper, field, listing);
}

maintenant un léger disclaimer:

  • ce n'est pas le code le plus rapide au monde (en raison de la réflexion et d'autres choses), dans ma situation ce n'est pas vraiment pertinent car tout est piloté par l'utilisateur, si vous prévoyez de faire quelque chose de fou stupide.
  • ce code en est à ses balbutiements, je vais le tester plus en profondeur et y ajouter au cours des prochains jours, ouvert à toute suggestion pour améliorer le code.

j'espère que ce code est utile à quelqu'un, je sais que je l'utiliserai au cours des prochaines semaines pour essayer de réduire le temps. Couper ceci vers le bas pour juste faire le bouton radio devrait être une tâche triviale, bonne chance:)

Jay

2
répondu Jay 2010-04-08 01:21:01

en Fonction dans Jon post , un petit à s'améliorer afin de générer le bouton radio liste ul avec HTMLAttributtes

public static MvcHtmlString RadioButtonListFor<TModel, TProperty>(
        this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression,
        IEnumerable<SelectListItem> listOfValues,
        IDictionary<string, object> radioHtmlAttributes = null,
        string ulClass = null)
    {
        ModelMetadata metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

        if (radioHtmlAttributes == null)
            radioHtmlAttributes = new RouteValueDictionary();

        TagBuilder ulTag = new TagBuilder("ul");
        if (!String.IsNullOrEmpty(ulClass))
            ulTag.MergeAttribute("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 = string.Format("{0}_{1}", metaData.PropertyName, item.Value);

                if (!radioHtmlAttributes.ContainsKey("id"))
                    radioHtmlAttributes.Add("id", id);
                else
                    radioHtmlAttributes["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, radioHtmlAttributes).ToHtmlString();

                // Create the html string that will be returned to the client 
                // e.g. <input data-val="true" data-val-required="You must select an option" id="TestRadio_1" name="TestRadio" type="radio" value="1" /><label for="TestRadio_1">Line1</label> 
                ulTag.InnerHtml += string.Format("<li>{0}{1}</li>", radio, label);
            }
        }

        return MvcHtmlString.Create(ulTag.ToString(TagRenderMode.Normal));
    }

    public static MvcHtmlString RadioButtonListFor<TModel, TProperty>(
        this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression,
        IEnumerable<SelectListItem> listOfValues,
        object radioHtmlAttributes = null,
        string ulClass = null)
    {
        return RadioButtonListFor<TModel, TProperty>(htmlHelper, expression, listOfValues, new RouteValueDictionary(radioHtmlAttributes), ulClass);
    }
2
répondu Pedre 2017-05-23 11:54:36

j'ai mis en place quelque chose de similaire dans MVC 1.0. Voyez si cela vous sera utile:

    public static string RadioButtonList2(this HtmlHelper _helper, string _name, IEnumerable<SelectListItem> _items, string _selectedValue, string _seperator)
    {
        return RadioButtonList2(_helper, _name, _items, _selectedValue, _seperator, null);
    }

    public static string RadioButtonList2(this HtmlHelper _helper, string _name, IEnumerable<SelectListItem> _items, string _selectedValue, string _seperator, IDictionary<string, object> _htmlAttributes)
    {
        StringBuilder _outputScript = new StringBuilder();

        foreach (var item in _items)
        {
            var optionField = new TagBuilder("input");
            optionField.MergeAttribute("name", _name);
            optionField.MergeAttribute("id", _name);
            optionField.MergeAttribute("class", _name);
            optionField.MergeAttribute("value", item.Value);
            optionField.MergeAttribute("type", "radio");

            // Check to see if it's checked
            if (item.Value == _selectedValue)
                optionField.MergeAttribute("checked", "checked");

            if (_htmlAttributes != null)
                optionField.MergeAttributes(_htmlAttributes);

            _outputScript.Append(optionField.ToString(TagRenderMode.SelfClosing));
            _outputScript.Append("<label style=\"display:inline;\">");
            _outputScript.Append(item.Text);
            _outputScript.Append("</label>" + _seperator);
        }

        return _outputScript.ToString();
    }

dans le controller, 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(), "&nbsp;")%>

vous pouvez aussi remplacer le &nbsp; par <BR /> pour les afficher sur des lignes séparées.

espérons que aider.

en ce qui Concerne Naweed Akram naweed@xgeno.com

1
répondu Naweed Akram 2010-03-25 07:27:33

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

<Extension()> _
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 htmlAttributes As Object) As System.Web.Mvc.MvcHtmlString
    'Return htmlHelper.DropDownListFor(expression, selectList, htmlAttributes)
    If selectList Is Nothing OrElse selectList.Count = 0 Then Return MvcHtmlString.Empty

    Dim divTag = New TagBuilder("div")
    divTag.MergeAttributes(New RouteValueDictionary(htmlAttributes))
    Dim name = CType(expression.Body, System.Linq.Expressions.MemberExpression).Member.Name
    Dim value = expression.Compile()(htmlHelper.ViewData.Model)
    Dim sb As New StringBuilder()

    For Each item In selectList
        sb.AppendFormat("<input id=""{0}_{1}"" type=""radio"" name=""{0}"" value=""{1}"" {2} />", name, item.Value, If(item.Value = value.ToString, """checked""", ""))
        sb.AppendFormat("<label for=""{0}_{1}"">{2}</label>", name, item.Value, item.Text)
    Next

    divTag.InnerHtml = sb.ToString

    Return MvcHtmlString.Create(divTag.ToString)

End Function
1
répondu Darragh 2014-12-15 11:39:38

j'ai modifié Mac's solution et remplacé Enum type par table de base de données, ma table est:

enter image description here

dans ma demande, je loue une chambre en fonction du sexe. Mon modèle avec la propriété GenderRadios:

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

dans le contrôleur de salle, je prépare des Radios:

   private void fillRadios(Room room)
    {         
        List<Gender> genders = fre.Genders.ToList();
        room.GenderRadios= new RadioButtonListViewModel();
        room.GenderRadios.ListItems = new List<RadioButtonListItem>();
        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 la salle:

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

et pour la salle de montage:

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

créer salle html ressemblera à:

<td id="GenderRadisoForRoomCreate_Container">
<input id="GenderRadisoForRoomCreate_Any" name="GenderRadisoForRoomCreate_value" value="1" type="radio"><label for="GenderRadisoForRoomCreate_Any">Any</label>
<input id="GenderRadisoForRoomCreate_Female" name="GenderRadisoForRoomCreate_value" value="2" type="radio"><label for="GenderRadisoForRoomCreate_Female">Female</label>
<input id="GenderRadisoForRoomCreate_Male" name="GenderRadisoForRoomCreate_value" value="3" type="radio"><label for="GenderRadisoForRoomCreate_Male">Male</label>
</td>

Lors de la salle créés:

[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 helpers:

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<RadioButtonListItem> listItems;
    public List<RadioButtonListItem> ListItems
    {
        get { return listItems; }
        set
        {
            listItems = value;
            UpdatedSelectedItems();
        }
    }
}

public class RadioButtonListItem
{
    public bool Selected { get; set; }

    public string Text { get; set; }



    public int Value { get; set; }

    public override string ToString()
    {
        return Value.ToString();
    }
}



public static class HtmlHelperExtensions
{
    /* 
     tagBase: I used tagBase string for building other tag's Id or Name on this. i.e. for tagBase="GenderRadiosForRoomCreate" 
        <td id="GenderRadisoForRoomCreate_Container">
        <input id="GenderRadisoForRoomCreate_Any" name="GenderRadisoForRoomCreate_value" value="1" type="radio"><label for="GenderRadisoForRoomCreate_Any">Any</label>
        <input id="GenderRadisoForRoomCreate_Female" name="GenderRadisoForRoomCreate_value" value="2" type="radio"><label for="GenderRadisoForRoomCreate_Female">Female</label>
        <input id="GenderRadisoForRoomCreate_Male" name="GenderRadisoForRoomCreate_value" value="3" type="radio"><label for="GenderRadisoForRoomCreate_Male">Male</label>
        </td>     
    */
    public static string RadioButtonListFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, RadioButtonListViewModel>> expression, String tagBase) where TModel : class
    {
        return htmlHelper.RadioButtonListFor(expression, tagBase, null);
    }

    public static string RadioButtonListFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, RadioButtonListViewModel>> expression, String tagBase, object htmlAttributes) where TModel : class
    {
        return htmlHelper.RadioButtonListFor(expression, tagBase, new RouteValueDictionary(htmlAttributes));
    }

    public static string RadioButtonListFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, RadioButtonListViewModel>> expression, String tagBase, IDictionary<string, object> htmlAttributes) where TModel : class
    {        
        var inputName = tagBase;
        RadioButtonListViewModel radioButtonList = GetValue(htmlHelper, expression);

        if (radioButtonList == null)
            return String.Empty;

        if (radioButtonList.ListItems == null)
            return String.Empty;


        var containerTag = new TagBuilder("td");
        containerTag.MergeAttribute("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.ToString()}, htmlAttributes);

            containerTag.InnerHtml += radioButtonTag;
        }

        return containerTag.ToString();
    }

    public static string RadioButton(this HtmlHelper htmlHelper, string name, SelectListItem listItem,
                         IDictionary<string, object> htmlAttributes)
    {
        var inputIdSb = new StringBuilder();
        inputIdSb.Append(name);

        var sb = new StringBuilder();

        var builder = new TagBuilder("input");
        if (listItem.Selected) builder.MergeAttribute("checked", "checked");
        builder.MergeAttribute("type", "radio");
        builder.MergeAttribute("value", listItem.Value);
        builder.MergeAttribute("id", inputIdSb.ToString() + "_" + listItem.Text);    
        builder.MergeAttribute("name", name + "_value");
        builder.MergeAttributes(htmlAttributes);
        sb.Append(builder.ToString(TagRenderMode.SelfClosing));
        sb.Append(RadioButtonLabel(inputIdSb.ToString(), listItem.Text, htmlAttributes));
        return sb.ToString();
    }

    public static string RadioButtonLabel(string inputId, string displayText,
                                 IDictionary<string, object> htmlAttributes)
    {
        var labelBuilder = new TagBuilder("label");
        labelBuilder.MergeAttribute("for", inputId + "_" + displayText);
        labelBuilder.MergeAttributes(htmlAttributes);
        labelBuilder.InnerHtml = displayText;

        return labelBuilder.ToString(TagRenderMode.Normal);
    }


    public static TProperty GetValue<TModel, TProperty>(HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) where TModel : class
    {
        TModel model = htmlHelper.ViewData.Model;
        if (model == null)
        {
            return default(TProperty);
        }
        Func<TModel, TProperty> func = expression.Compile();
        return func(model);
    }
}
0
répondu asdf_enel_hak 2011-06-15 11:17:16