简体   繁体   English

MVC5:Enum单选按钮,标签为displayname

[英]MVC5: Enum radio button with label as displayname

I have these enums 我有这些枚举

public enum QuestionStart
{
    [Display(Name="Repeat till common match is found")]
    RepeatTillCommonIsFound,

    [Display(Name="Repeat once")]
    RepeatOnce,    

    [Display(Name="No repeat")]
    NoRepeat

}

public enum QuestionEnd
{
    [Display(Name="Cancel Invitation")]
    CancelInvitation,

    [Display(Name="Plan with participants on first available common date")]
    FirstAvailableCommon,

    [Display(Name="Plan with participants on my first available common date")]
    YourFirstAvailableCommon
}

and I have a helper class to show all the radiobutton for each field in enum 我有一个帮助类来显示枚举中每个字段的所有单选按钮

@model Enum
@foreach (var value in Enum.GetValues(Model.GetType()))
{
    @Html.RadioButtonFor(m => m, value)
    @Html.Label(value.ToString())
    <br/>
}

Right now the label is set to the value name and not the display name i have given for values. 现在标签设置为值名称,而不是我为值给出的显示名称。

For example for: 例如:

[Display(Name="Cancel Invitation")]
CancelInvitation

I get radio button with CancelInvitation next to it. 我在旁边有CancelInvitation单选按钮。

How can I make it display the Display name( Cancel Invitation ) i have given to it? 如何让它显示我给它的显示名称( Cancel Invitation )?

Here goes the solution - 这是解决方案 -

Credit goes to this extraordinary gentleman - ThumNet, who wrote RadioButtonList for Enum as an extension 归功于这位非凡的绅士--ThumNet,他为Enum编写了RadioButtonList作为扩展

Step 1 - Create RadioButtonListEnum.cshtml file with below code (code from above reference) in Views/Shared/EditorTemplates directory (if not exist, then create that directory) - 步骤1 -Views / Shared / EditorTemplates目录中创建带有以下代码(来自上面引用的代码)的RadioButtonListEnum.cshtml文件(如果不存在,则创建该目录) -

@model Enum

@{
     // Looks for a [Display(Name="Some Name")] or a [Display(Name="Some Name", ResourceType=typeof(ResourceFile)] Attribute on your enum
    Func<Enum, string> getDescription = en =>
    {
        Type type = en.GetType();
        System.Reflection.MemberInfo[] memInfo = type.GetMember(en.ToString());

        if (memInfo != null && memInfo.Length > 0)
        {

            object[] attrs = memInfo[0].GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.DisplayAttribute),
                                                            false);

            if (attrs != null && attrs.Length > 0)
                return ((System.ComponentModel.DataAnnotations.DisplayAttribute)attrs[0]).GetName();
        }

        return en.ToString();
    };
    var listItems = Enum.GetValues(Model.GetType()).OfType<Enum>().Select(e =>
    new SelectListItem()
    {
        Text = getDescription(e),
        Value = e.ToString(),
        Selected = e.Equals(Model)
    });
    string prefix = ViewData.TemplateInfo.HtmlFieldPrefix;
    int index = 0;
    ViewData.TemplateInfo.HtmlFieldPrefix = string.Empty;

    foreach (var li in listItems)
    {
        string fieldName = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}_{1}", prefix, index++);
        <div class="editor-radio">
        @Html.RadioButton(prefix, li.Value, li.Selected, new { @id = fieldName }) 
        @Html.Label(fieldName, li.Text)    
        </div>
    }
    ViewData.TemplateInfo.HtmlFieldPrefix = prefix;
}

Then have your enum - 然后有你的枚举 -

public enum QuestionEnd
{
    [Display(Name = "Cancel Invitation")]
    CancelInvitation,

    [Display(Name = "Plan with participants on first available common date")]
    FirstAvailableCommon,

    [Display(Name = "Plan with participants on my first available common date")]
    YourFirstAvailableCommon
}

Step 2 - Create Model - 第2步 -创建模型 -

public class RadioEnumModel
{
    public QuestionEnd qEnd { get; set; }
}

Step 3 - Create Controller Action - 第3步 -创建控制器操作 -

    public ActionResult Index()
    {
        RadioEnumModel m = new RadioEnumModel();
        return View(m);
    }

Step 4 - Create View - 第4步 -创建视图 -

@model MVC.Controllers.RadioEnumModel
@Html.EditorFor(x => x.qEnd, "RadioButtonListEnum")

Then the output would be - 然后输出将是 -

在此输入图像描述

I found some of these answers confusing, this is how I ended up achieving the result. 我发现其中一些答案令人困惑,这就是我最终实现结果的方式。 Hopefully this helps someone else. 希望这有助于其他人。

Shove this in an extension methods file: 在扩展方法文件中推送它:

public static string GetDescription(this Enum value)
{
    Type type = value.GetType();
    string name = Enum.GetName(type, value);
    if (name != null)
    {
        FieldInfo field = type.GetField(name);
        if (field != null)
        {
            DescriptionAttribute attr =
                   Attribute.GetCustomAttribute(field,
                     typeof(DescriptionAttribute)) as DescriptionAttribute;
            if (attr != null)
            {
                return attr.Description;
            }
        }
    }
    return null;
}

Make sure you add a property that is the same type as your enum to your actual Model so that the radio button selection binds. 确保在实际模型中添加与枚举类型相同的属性,以便选择单选按钮。

Create an editor template for your particular enum. 为您的特定枚举创建一个编辑器模板。 Then in your view reference it like so: 然后在您的视图中引用它如下:

@Html.EditorFor(m => m.MyEnumTypePropertyName)

Then add the following to your EditorTemplate: 然后将以下内容添加到EditorTemplate:

@using MyProject.ExtensionMethods;
@model MyProject.Models.Enums.MyEnumType

    @foreach (MyEnumType value in Enum.GetValues(typeof(MyEnumType)))
    {
        <div>
            @Html.Label(value.GetDescription())
            @Html.RadioButtonFor(m => m, value)
        </div>
    }

Remember - If you don't select a radio button for whatever reason, the default value for your enum property when posted will always be the first in the pack (ie zero), not null. 记住 - 如果由于某种原因没有选择单选按钮,发布时枚举属性的默认值将始终是包中的第一个(即零),而不是null。

You can use the following overload method. 您可以使用以下重载方法。

@Html.Label(value.ToString(),"Cancel Invitation")

This will render the label with specified labeltext provided as second parameter in above call. 这将使标签具有指定的labeltext作为上述调用中的第二个参数。

Here is a solution that uses an extension method and an editor template to create a radio group with a localized name from the display attribute. 这是一个解决方案,它使用扩展方法和编辑器模板从display属性创建一个具有本地化名称的无线电组。

Extension Method 扩展方法

public static string DisplayName(this Enum enumValue)
{
    var enumType = enumValue.GetType();
    var memberInfo = enumType.GetMember(enumValue.ToString()).First();

    if (memberInfo == null || !memberInfo.CustomAttributes.Any()) return enumValue.ToString();

    var displayAttribute = memberInfo.GetCustomAttribute<DisplayAttribute>();

    if (displayAttribute == null) return enumValue.ToString();

    if (displayAttribute.ResourceType != null && displayAttribute.Name != null)
    {
        var manager = new ResourceManager(displayAttribute.ResourceType);
        return manager.GetString(displayAttribute.Name);
    }

    return displayAttribute.Name ?? enumValue.ToString();
}

Example

public enum IndexGroupBy 
{
    [Display(Name = "By Alpha")]
    ByAlpha,
    [Display(Name = "By Type")]
    ByType
}

And here is its usage: 这是它的用法:

@IndexGroupBy.ByAlpha.DisplayName()

Editor Template 编辑模板

Here is an editor template that can be used with the extension method above: 这是一个可以与上面的扩展方法一起使用的编辑器模板:

@model Enum

@{    
    var listItems = Enum.GetValues(Model.GetType()).OfType<Enum>().Select(e =>
        new SelectListItem
        {
            Text = e.DisplayName(),
            Value = e.ToString(),
            Selected = e.Equals(Model)
        });
    var prefix = ViewData.TemplateInfo.HtmlFieldPrefix;
    var index = 0;
    ViewData.TemplateInfo.HtmlFieldPrefix = string.Empty;

    foreach (var li in listItems)
    {
        var fieldName = string.Format(CultureInfo.InvariantCulture, "{0}_{1}", prefix, index++);
        <div class="editor-radio">
            @Html.RadioButton(prefix, li.Value, li.Selected, new {@id = fieldName})
            @Html.Label(fieldName, li.Text)
        </div>
    }
    ViewData.TemplateInfo.HtmlFieldPrefix = prefix;
}

And here is an example usage: 以下是一个示例用法:

@Html.EditorFor(m => m.YourEnumMember, "Enum_RadioButtonList")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM