MVC3 रेजर ड्रॉपडाउन लिस्टफ़ोर एनम


84

मेरी परियोजना को MVC3 में अपडेट करने की कोशिश कर रहा है, कुछ ऐसा जो मुझे अभी नहीं मिला है:

मेरे पास ENUMS का एक सरल प्रारूप है:

public enum States()
{
  AL,AK,AZ,...WY
}

जिसे मैं एक ड्रॉपडाउन / SelectList के रूप में उपयोग करना चाहता हूं मेरे मॉडल में यह डेटाटाइप शामिल है:

public class FormModel()
{
    public States State {get; set;}
}

बहुत सीधे आगे: जब मैं इस आंशिक वर्ग के लिए ऑटो-जनरेट दृश्य का उपयोग करने जाता हूं, तो यह इस प्रकार की उपेक्षा करता है।

मुझे एक सरल चयन सूची की आवश्यकता है जो चयनित आइटम के रूप में एनम का मान सेट करता है जब मैंने सबमिट किया और मेरे AJAX - JSON POST विधि के माध्यम से प्रक्रिया की।

और देखने से (???):

    <div class="editor-field">
        @Html.DropDownListFor(model => model.State, model => model.States)
    </div>

सलाह के लिए अग्रिम धन्यवाद!


8
किसी के लिए भी है जो इस धागे भर आता है और MVC 5.1 या इसके बाद के संस्करण, सहायक विधि @ Html.EnumDropDownListFor () अब MVC करने के लिए बनाया गया है का उपयोग कर सकती है - asp.net/mvc/overview/releases/mvc51-release-notes
mecsco

जवाबों:


55

मैंने सिर्फ अपने प्रोजेक्ट के लिए एक बनाया है। नीचे दिया गया कोड मेरे सहायक वर्ग का हिस्सा है, मुझे उम्मीद है कि मुझे सभी तरीकों की जरूरत है। यह काम नहीं करता है, तो एक टिप्पणी लिखें, और मैं फिर से जाँच करूँगा।

public static class SelectExtensions
{

    public static string GetInputName<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression)
    {
        if (expression.Body.NodeType == ExpressionType.Call)
        {
            MethodCallExpression 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...
        MethodCallExpression methodCallExpression = expression.Object as MethodCallExpression;
        if (methodCallExpression != null)
        {
            return GetInputName(methodCallExpression);
        }
        return expression.Object.ToString();
    }

    public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) where TModel : class
    {
        string inputName = GetInputName(expression);
        var value = htmlHelper.ViewData.Model == null
            ? default(TProperty)
            : expression.Compile()(htmlHelper.ViewData.Model);

        return htmlHelper.DropDownList(inputName, ToSelectList(typeof(TProperty), value.ToString()));
    }

    public static SelectList ToSelectList(Type enumType, string selectedItem)
    {
        List<SelectListItem> items = new List<SelectListItem>();
        foreach (var item in Enum.GetValues(enumType))
        {
            FieldInfo fi = enumType.GetField(item.ToString());
            var attribute = fi.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault();
            var title = attribute == null ? item.ToString() : ((DescriptionAttribute)attribute).Description;
            var listItem = new SelectListItem
                {
                    Value = ((int)item).ToString(),
                    Text = title,
                    Selected = selectedItem == ((int)item).ToString()
                };
            items.Add(listItem);
        }

        return new SelectList(items, "Value", "Text", selectedItem);
    }
}

इसे इस रूप में उपयोग करें:

Html.EnumDropDownListFor(m => m.YourEnum);

अपडेट करें

मैंने वैकल्पिक एचटीएमएल हेल्पर्स बनाया है। आपको उनका उपयोग करने के लिए बस इतना करना है कि आपको अपना आधार-पृष्ठ बदलना है views\web.config

उनके साथ आप बस कर सकते हैं:

@Html2.DropDownFor(m => m.YourEnum);
@Html2.CheckboxesFor(m => m.YourEnum);
@Html2.RadioButtonsFor(m => m.YourEnum);

अधिक जानकारी यहाँ: http://blog.gauffin.org/2011/10/first-draft-of-my-alternative-html-helpers/


1
ठीक है यह किसी भी तरह से काम करता है, मैं सिर्फ एक संकलन त्रुटि प्राप्त कर रहा हूं: लाइन 41: html htmlelper.DropDownList (inputName, ToSelectList (typeof (TProperty)), value.ToString ())); 'System.Web.Mvc.HtmlHelper <TModel>' में 'DropDownList' के लिए कोई परिभाषा नहीं है और न ही कोई एक्सटेंशन विधि 'DropDownList' प्रकार का पहला तर्क स्वीकार करते हुए 'System.Web.Mvc.Hmlmlelelel <TModel>' पाया जा सकता है ( क्या आप एक निर्देश या एक विधानसभा संदर्भ का उपयोग कर याद कर रहे हैं?)
jordan.baucke

1
@ जोर्डन मैं वही त्रुटि है। क्या आपने समस्या को ठीक करने का प्रबंधन किया था?
एसएफ डेवलपर

9
@filu @jordan जोड़ने के using System.Web.Mvc.Html;रूप में आप तक पहुँचने की जरूरत हैSelectExtensionsClass
साइमन हार्टचर

3
@ पारा मुझे एक ही मुद्दा मिल रहा है, चयनित मूल्य दृश्य में चयनित नहीं है। (मैं बदलना पड़ा ((int)item).ToString()के लिए Enum.GetName(enumType, item)प्राप्त करने के लिए SelectListItemसही ढंग से चुने गए के रूप में सहेजा है, लेकिन यह अभी भी काम नहीं करता है)
फर्नांडो नीरा

1
बस नीचे एक उत्तर जोड़ा गया है जो चयन के मुद्दे को कवर करता है - ड्रॉपडाउनलिस्ट ओवरलोड के व्यवहार की गलतफहमी से उपजा है।
जॉन एगर्टन

199

मुझे यहाँ इसके लिए एक सरल तरीका मिल गया: http://coding-in.net/asp-net-mvc-3-method.extn/

using System;
using System.Linq.Expressions;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace EnumHtmlHelper.Helper
{    
    public static class EnumDropDownList
    {
        public static HtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> modelExpression, string firstElement)
        {
            var typeOfProperty = modelExpression.ReturnType;
            if(!typeOfProperty.IsEnum)
                throw new ArgumentException(string.Format("Type {0} is not an enum", typeOfProperty));     
            var enumValues = new SelectList(Enum.GetValues(typeOfProperty));
            return htmlHelper.DropDownListFor(modelExpression, enumValues, firstElement);
}   }   }

रेजर में एक लाइन यह करेगी:

@Html.DropDownListFor(model => model.State, new SelectList(Enum.GetValues(typeof(MyNamespace.Enums.States))))

आप इसे लिंक किए गए लेख में एक एक्सटेंशन विधि के साथ करने के लिए कोड भी पा सकते हैं।


6
मुझे लगता है कि इसे समाधान के रूप में चिह्नित किया जाना चाहिए था। सबसे अच्छा जटिलता से चिह्नित नहीं है, लेकिन सरलता से।
लिपियों के भगवान

3
ड्रॉपडोलिस्ट संस्करण (मेरे जैसे) देखने वाले लोगों के लिए: @ Html.DropDownList ("listName", नया SelectList (Enum.GetValues ​​(typeof (MyNamespace.Enums.States)))
dstr

2
@JonEgerton यदि आप मेरे जैसा ही मतलब रखते हैं तो मैं सहमत हूं। यदि आप enums + विवरण + को प्रदर्शित करना चाहते हैं, तो आप एक छवि को मैक मैकलॉघलिन के समाधान के साथ खो गए हैं।
एलिजाबेथ

1
इस समाधान के साथ मैंने जो एकमात्र समस्या पाई है, वह यह है कि इसे लोड करते समय चयनित मूल्य को सही ढंग से मैप नहीं किया जाता है। उस के अलावा, बहुत अच्छा है।
त्रिकोणीयितो

3
@triangulito यह कोई समस्या नहीं है :)@Html.DropDownListFor(model => model.State, new SelectList(Enum.GetValues(typeof(MyNamespace.Enums.States)),model.State))
व्लाद


17

यदि आप वास्तव में कुछ सरल चाहते हैं तो एक और तरीका है, जो इस बात पर निर्भर करता है कि आप डेटाबेस में राज्य को कैसे स्टोर करते हैं।

यदि आपके पास इस तरह की एक इकाई है:

public class Address
{
     //other address fields

     //this is what the state gets stored as in the db
     public byte StateCode { get; set; }

     //this maps our db field to an enum
     public States State
     {
         get
         {
             return (States)StateCode;
         }
         set
         {
             StateCode = (byte)value;
         }
     }
}

फिर ड्रॉपडाउन उत्पन्न करना इस रूप में आसान होगा:

@Html.DropDownListFor(x => x.StateCode,
    from State state in Enum.GetValues(typeof(States))
    select new SelectListItem() { Text = state.ToString(), Value = ((int)state).ToString() }
);

LINQ सुंदर नहीं है?


आप मॉडल या दृश्य में स्टेट्स एनम को कहाँ परिभाषित करते हैं?
सुपरनाइट्स

मॉडल में, जैसा कि मॉडल वर्ग द्वारा उपयोग किया जाता है
sjmeverett

1
@stewartml जब मेरे ViewModel के पास एनुम संपत्ति + "चयनितकोडप्रोपरेटी" है तो यह आपके पोस्ट में बहुत अधिक संपत्ति है। चयनित मूल्य मान के रूप में सर्वर + आइटम मान के रूप में दोनों में एनम क्यों नहीं है।
एलिजाबेथ

13

मैं एक लाइनर में ऐसा करने में सक्षम था।

@Html.DropDownListFor(m=>m.YourModelProperty,new SelectList(Enum.GetValues(typeof(YourEnumType))))

8

@Jgauffin द्वारा स्वीकृत उत्तर के आधार पर, मैंने अपना स्वयं का संस्करण बनाया है EnumDropDownListFor, जो आइटमों के चयन की समस्या से निपटता है।

समस्या यहाँ एक और एसओ उत्तर में विस्तृत है : और मूल रूप से विभिन्न अधिभार के व्यवहार की गलतफहमी के लिए नीचे है DropDownList

मेरा पूरा कोड (जिसमें htmlAttributesआदि के लिए अधिभार शामिल है):

public static class EnumDropDownListForHelper
{

    public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(
            this HtmlHelper<TModel> htmlHelper, 
            Expression<Func<TModel, TProperty>> expression
        ) where TModel : class
    {
        return EnumDropDownListFor<TModel, TProperty>(
                            htmlHelper, expression, null, null);
    }

    public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(
            this HtmlHelper<TModel> htmlHelper, 
            Expression<Func<TModel, TProperty>> expression, 
            object htmlAttributes
        ) where TModel : class
    {
        return EnumDropDownListFor<TModel, TProperty>(
                            htmlHelper, expression, null, htmlAttributes);
    }

    public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(
            this HtmlHelper<TModel> htmlHelper, 
            Expression<Func<TModel, TProperty>> expression, 
            IDictionary<string, object> htmlAttributes
        ) where TModel : class
    {
        return EnumDropDownListFor<TModel, TProperty>(
                            htmlHelper, expression, null, htmlAttributes);
    }

    public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(
            this HtmlHelper<TModel> htmlHelper, 
            Expression<Func<TModel, TProperty>> expression, 
            string optionLabel
        ) where TModel : class
    {
        return EnumDropDownListFor<TModel, TProperty>(
                            htmlHelper, expression, optionLabel, null);
    }

    public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(
            this HtmlHelper<TModel> htmlHelper, 
            Expression<Func<TModel, TProperty>> expression, 
            string optionLabel, 
            IDictionary<string,object> htmlAttributes
        ) where TModel : class
    {
        string inputName = GetInputName(expression);
        return htmlHelper.DropDownList(
                            inputName, ToSelectList(typeof(TProperty)), 
                            optionLabel, htmlAttributes);
    }

    public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(
            this HtmlHelper<TModel> htmlHelper, 
            Expression<Func<TModel, TProperty>> expression, 
            string optionLabel, 
            object htmlAttributes
        ) where TModel : class
    {
        string inputName = GetInputName(expression);
        return htmlHelper.DropDownList(
                            inputName, ToSelectList(typeof(TProperty)), 
                            optionLabel, htmlAttributes);
    }


    private static string GetInputName<TModel, TProperty>(
            Expression<Func<TModel, TProperty>> expression)
    {
        if (expression.Body.NodeType == ExpressionType.Call)
        {
            MethodCallExpression 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...
        MethodCallExpression methodCallExpression 
                            = expression.Object as MethodCallExpression;
        if (methodCallExpression != null)
        {
            return GetInputName(methodCallExpression);
        }
        return expression.Object.ToString();
    }


    private static SelectList ToSelectList(Type enumType)
    {
        List<SelectListItem> items = new List<SelectListItem>();
        foreach (var item in Enum.GetValues(enumType))
        {
            FieldInfo fi = enumType.GetField(item.ToString());
            var attribute = fi.GetCustomAttributes(
                                       typeof(DescriptionAttribute), true)
                                  .FirstOrDefault();
            var title = attribute == null ? item.ToString() 
                              : ((DescriptionAttribute)attribute).Description;
            var listItem = new SelectListItem
            {
                Value = item.ToString(),
                Text = title,
            };
            items.Add(listItem);
        }

        return new SelectList(items, "Value", "Text");
    }
}

मैंने इसे अपने ब्लॉग पर यहाँ लिखा है


1
यह एकमात्र समाधान है जो मैं भर में आया हूं जो मेरी गणना के लिए प्रासंगिक मूल्य को सही ढंग से पूर्व-चयन करता है। धन्यवाद!
एडविन ग्रोएनडेनल

बहुत बढ़िया। यह निश्चित रूप से स्वीकृत उत्तर होना चाहिए - यह काम करता है; स्वीकृत उत्तर नहीं है।
नीमिनम

3

यह एनम से एक अंतर मूल्य का चयन करने के लिए उपयोगी होगा: यहाँ SpecTypeएक intक्षेत्र है ... और enmSpecTypeएक है enum

@Html.DropDownList(
    "SpecType", 
     YourNameSpace.SelectExtensions.ToSelectList(typeof(NREticaret.Core.Enums.enmSpecType), 
     Model.SpecType.ToString()), "Tip Seçiniz", new 
     { 
         gtbfieldid = "33", 
         @class = "small" 
     })

3

मैंने इसे अपने लिए थोड़ा बेहतर बनाने के लिए SelectList पद्धति में निम्नलिखित बदलाव किए। शायद यह दूसरों के लिए उपयोगी होगा।

public static SelectList ToSelectList<T>(T selectedItem)
        {
            if (!typeof(T).IsEnum) throw new InvalidEnumArgumentException("The specified type is not an enum");

            var selectedItemName = Enum.GetName(typeof (T), selectedItem);
            var items = new List<SelectListItem>();
            foreach (var item in Enum.GetValues(typeof(T)))
            {
                var fi = typeof(T).GetField(item.ToString());
                var attribute = fi.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault();

                var enumName = Enum.GetName(typeof (T), item);
                var title = attribute == null ? enumName : ((DescriptionAttribute)attribute).Description;

                var listItem = new SelectListItem
                {
                    Value = enumName,
                    Text = title,
                    Selected = selectedItemName == enumName
                };
                items.Add(listItem);
            }

            return new SelectList(items, "Value", "Text");
        }

3
    public enum EnumStates
    {
        AL = 0,
        AK = 1,
        AZ = 2,
        WY = 3
    }


@Html.DropDownListFor(model => model.State, (from EnumStates e in Enum.GetValues(typeof(EnumStates))
                                                               select new SelectListItem { Value = ((int)e).ToString(), Text = e.ToString() }), "select", new { @style = "" })
                @Html.ValidationMessageFor(model => model.State)  //With select



//Or


@Html.DropDownListFor(model => model.State, (from EnumStates e in Enum.GetValues(typeof(EnumStates))
                                                               select new SelectListItem { Value = ((int)e).ToString(), Text = e.ToString() }), null, new { @style = "" })
                @Html.ValidationMessageFor(model => model.State)   //With out select

आप EnumState को कहाँ परिभाषित करते हैं?
सुपरनाइट्स

शीर्ष u में इसे देख सकते हैं ... सार्वजनिक enum EnumStates
थुलसीराम

2

माइक के रूप में भी (जो लंबी प्रतिक्रियाओं के बीच दफन है)

model.truckimagelocation TruckImageLocation एन्यूमरेशन प्रकार की श्रेणी उदाहरण संपत्ति है

@Html.DropDownListFor(model=>model.truckimagelocation,Enum.GetNames(typeof(TruckImageLocation)).ToArray().Select(f=> new SelectListItem() {Text = f, Value = f, Selected = false}))

2

यह सबसे सामान्य कोड है जो सभी Enums के लिए उपयोग किया जाएगा।

public static class UtilitiesClass
{

    public static SelectList GetEnumType(Type enumType)
    {
        var value = from e in Enum.GetNames(enumType)
                    select new
                    {
                        ID = Convert.ToInt32(Enum.Parse(enumType, e, true)),
                        Name = e
                    };
        return new SelectList(value, "ID", "Name");
    }
}

क्रिया विधि

ViewBag.Enum= UtilitiesClass.GetEnumType(typeof (YourEnumType));

View.cshtml

 @Html.DropDownList("Type", (IEnumerable<SelectListItem>)ViewBag.Enum, new { @class = "form-control"})

1

आप अपने मॉडल में एनम का उपयोग कर सकते हैं

आपकी Enum

public enum States()
{
  AL,AK,AZ,...WY
}

मॉडल बनाओ

public class enumclass
{
public States statesprop {get; set;}
}

दृश्य में

@Html.Dropdownlistfor(a=>a.statesprop)

नवीनतम प्रश्न उत्तर कर।
अनूप

1

MVC5 में सबसे आसान जवाब परिभाषित एनम है:

public enum ReorderLevels {
          zero = 0,
            five = 5,
            ten = 10,
            fifteen = 15,
            twenty = 20,
            twenty_five = 25,
            thirty = 30
        }

दृश्य में बांधें:

        <div class="form-group">
            <label>Reorder Level</label>
            @Html.EnumDropDownListFor(m => m.ReorderLevel, "Choose Me", new { @class = "form-control" })
        </div>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.