आप ASP.NET में एक ड्रॉपडाउनलिस्ट नियंत्रण के लिए एनम को कैसे बांधते हैं?


126

मान लें कि मेरे पास निम्नलिखित सरल एनम हैं:

enum Response
{
    Yes = 1,
    No = 2,
    Maybe = 3
}

मैं इस एनम को ड्रॉपडाउनलिस्ट कंट्रोल से कैसे बांध सकता हूं ताकि विवरण सूची में प्रदर्शित हो और साथ ही एक विकल्प चुने जाने के बाद संबंधित संख्यात्मक मान (1,2,3) प्राप्त हो सके?

जवाबों:


112

मैं शायद डेटा को बाँध नहीं सकता क्योंकि यह एक एनम है, और यह संकलन समय के बाद नहीं बदलेगा (जब तक कि मैं उन निष्फल क्षणों में से एक नहीं हूं )।

केवल एनम के माध्यम से पुनरावृति करने के लिए बेहतर:

Dim itemValues As Array = System.Enum.GetValues(GetType(Response))
Dim itemNames As Array = System.Enum.GetNames(GetType(Response))

For i As Integer = 0 To itemNames.Length - 1
    Dim item As New ListItem(itemNames(i), itemValues(i))
    dropdownlist.Items.Add(item)
Next

या C # में समान

Array itemValues = System.Enum.GetValues(typeof(Response));
Array itemNames = System.Enum.GetNames(typeof(Response));

for (int i = 0; i <= itemNames.Length - 1 ; i++) {
    ListItem item = new ListItem(itemNames[i], itemValues[i]);
    dropdownlist.Items.Add(item);
}

1
इस उत्तर के लिए बहुत बहुत धन्यवाद। GetType (प्रतिक्रिया) ने मेरे लिए काम नहीं किया क्योंकि मुझे Enum क्लास के बजाय Enum का एक उदाहरण प्राप्त हुआ। इसलिए मैं इसके बजाय enumInstance.GetType () का उपयोग करता हूं।
सेबेस्टियन

2
C # का उपयोग करना, यह मेरे लिए काम नहीं कर रहा है, क्योंकि getValues ​​और getNames दोनों समान हैं, पहला ऑब्जेक्ट की तरह और दूसरा स्ट्रिंग की तरह। एनम की परिभाषा इस तरह से है: सार्वजनिक एनम eResult {Right = 1, नॉनकंट्रोलर Error = 2,}
Javiere

9
C # के माध्यम से, आप अनुक्रमणिका आइटम नाम के साथ ऐरे तक नहीं पहुँच सकते [i], आप इसे केवल arrayObject.GetValue (i) के साथ कर सकते हैं और इस तरह से, यह दोनों मामलों में सिर्फ नाम वापस कर सकता है।
जेवियर

1
मैं इसे इस एक के साथ इस समाधान मिश्रण हल stackoverflow.com/questions/3213432/...
Javiere

5
ऐसा क्यों होता है? कोड (कम से कम c #) अब काम करता है और इसमें सिंटैक्स त्रुटियां हैं।
डेव

69

एन्यूमरेशन से (Enum value & name pair) Enumerationपाने के लिए निम्न उपयोगिता वर्ग का उपयोग करें ; आप तो बाँध IDictionary एक bindable नियंत्रण करने के लिए।IDictionary<int,string>

public static class Enumeration
{
    public static IDictionary<int, string> GetAll<TEnum>() where TEnum: struct
    {
        var enumerationType = typeof (TEnum);

        if (!enumerationType.IsEnum)
            throw new ArgumentException("Enumeration type is expected.");

        var dictionary = new Dictionary<int, string>();

        foreach (int value in Enum.GetValues(enumerationType))
        {
            var name = Enum.GetName(enumerationType, value);
            dictionary.Add(value, name);
        }

        return dictionary;
    }
}

उदाहरण: एन्युमरेशन डेटा को नियंत्रण में बाँधने के लिए यूटिलिटी क्लास का उपयोग करना

ddlResponse.DataSource = Enumeration.GetAll<Response>();
ddlResponse.DataTextField = "Value";
ddlResponse.DataValueField = "Key";
ddlResponse.DataBind();

1
+1। मैंने इसका उपयोग किया है, लेकिन मुझे लगता है कि कुंजी और मूल्य गलत तरीके से गोल हैं। यह एक IDEDIA लौटना चाहिए <string, int>
Colin

यह ध्यान दिया जाना चाहिए कि यह सभी ईनम प्रकारों (जैसे कि यूंट, उलॉन्ग, लॉन्ग, इत्यादि) का सही ढंग से व्यवहार नहीं करेगा। आम तौर पर खोज करने के लिए सबसे कुशल फ़ील्ड कुंजी है। इस स्थिति में पूर्णांक एक सरल <, =,> तुलना बनाम एक स्ट्रिंग की <और> प्रत्येक चार्ट के लिए तुलना के बाद से int होगा।
Trisped

43

मैं ASP.NET MVC के लिए इसका उपयोग करता हूं :

Html.DropDownListFor(o => o.EnumProperty, Enum.GetValues(typeof(enumtype)).Cast<enumtype>().Select(x => new SelectListItem { Text = x.ToString(), Value = ((int)x).ToString() }))

36

मेरा संस्करण उपर्युक्त का संक्षिप्त रूप है:

foreach (Response r in Enum.GetValues(typeof(Response)))
{
    ListItem item = new ListItem(Enum.GetName(typeof(Response), r), r.ToString());
    DropDownList1.Items.Add(item);
}

4
होना चाहिए (Enum.GetValues ​​(टाइपोफ़ (रिस्पांस)) में int r) या यह सिर्फ नाम और मूल्य के रूप में विवरण को बांध देगा ...
इवान

2
यह काम नहीं करता है, क्योंकि यह ListItem के मूल्य में गणना सदस्य का नाम सम्मिलित करता है। इंट में बदलना ज्यादातर मामलों में काम करेगा, लेकिन यह नहीं कि एनम एक यूइंट, उलॉन्ग या लंबा है।
त्रिशूल

ज्यादा बेहतर समाधान IMHO।
विप्पी

23
public enum Color
{
    RED,
    GREEN,
    BLUE
}

हर Enum टाइप System.Enum से निकलता है। दो स्थिर विधियाँ हैं जो डेटा को एक ड्रॉप-डाउन सूची नियंत्रण में बाँधने में मदद करती हैं (और मान को पुनः प्राप्त करती हैं)। ये Enum.GetNames और Enum.Parse हैं। GetNames का उपयोग करते हुए, आप अपने ड्रॉप-डाउन सूची नियंत्रण को निम्नानुसार बांधने में सक्षम हैं:

protected System.Web.UI.WebControls.DropDownList ddColor;

private void Page_Load(object sender, System.EventArgs e)
{
     if(!IsPostBack)
     {
        ddColor.DataSource = Enum.GetNames(typeof(Color));
        ddColor.DataBind();
     }
}

अब यदि आप Enum value को Selection पर वापस चाहते हैं ...।

  private void ddColor_SelectedIndexChanged(object sender, System.EventArgs e)
  {
    Color selectedColor = (Color)Enum.Parse(typeof(Color),ddColor.SelectedValue
  }

2
अच्छा उत्तर लेकिन थोड़ा टिप: रंग चयनित रंग = (रंग) Enum.Parse (टाइपोफ़ (रंग), ddColor.SelectedValue);
sma6871

11

सभी पोस्ट पढ़ने के बाद, मैं ड्रॉपडाउन सूची में एनम विवरण दिखाने के साथ-साथ संपादन मोड में प्रदर्शित होने पर ड्रॉपडाउन में मॉडल से उचित मूल्य का चयन करने के लिए एक व्यापक समाधान के साथ आया:

enum:

using System.ComponentModel;
public enum CompanyType
{
    [Description("")]
    Null = 1,

    [Description("Supplier")]
    Supplier = 2,

    [Description("Customer")]
    Customer = 3
}

एनम विस्तार वर्ग:

using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web.Mvc;

public static class EnumExtension
{
    public static string ToDescription(this System.Enum value)
    {
        var attributes = (DescriptionAttribute[])value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
        return attributes.Length > 0 ? attributes[0].Description : value.ToString();
    }

    public static IEnumerable<SelectListItem> ToSelectList<T>(this System.Enum enumValue)
    {
        return
            System.Enum.GetValues(enumValue.GetType()).Cast<T>()
                  .Select(
                      x =>
                      new SelectListItem
                          {
                              Text = ((System.Enum)(object) x).ToDescription(),
                              Value = x.ToString(),
                              Selected = (enumValue.Equals(x))
                          });
    }
}

मॉडल वर्ग:

public class Company
{
    public string CompanyName { get; set; }
    public CompanyType Type { get; set; }
}

और देखें:

@Html.DropDownListFor(m => m.Type,
@Model.Type.ToSelectList<CompanyType>())

और यदि आप उस ड्रॉपडाउन का उपयोग मॉडल से जुड़े बिना कर रहे हैं, तो आप इसके बजाय इसका उपयोग कर सकते हैं:

@Html.DropDownList("type",                  
Enum.GetValues(typeof(CompanyType)).Cast<CompanyType>()
.Select(x => new SelectListItem {Text = x.ToDescription(), Value = x.ToString()}))

तो ऐसा करके आप अपने ड्रॉपडाउन प्रदर्शनों की अपेक्षा कर सकते हैं कि एनम मानों के बजाय विवरण। इसके अलावा जब यह संपादन की बात आती है, तो पोस्टिंग पृष्ठ के बाद आपके मॉडल को ड्रॉपडाउन चयनित मूल्य से अपडेट किया जाएगा।


1
अच्छी तरह से किया, विशेष रूप से बिट [विवरण] एनोटेशन के साथ। मैं इस तकनीक को अपनाऊंगा।
बैक्सटर

साफ और स्वच्छ व्याख्या। कुदोस अमीर !!

8

जैसा कि अन्य लोग पहले ही कह चुके हैं - जब तक आपको स्थिति के आधार पर विभिन्न एनमों को बाँधने की आवश्यकता नहीं है, तब तक किसी एनम को डेटाबाइंड न करें। ऐसा करने के कई तरीके हैं, नीचे दिए गए कुछ उदाहरण।

ObjectDataSource

ObjectDataSource के साथ इसे करने का एक घोषणात्मक तरीका। सबसे पहले, एक BusinessObject क्लास बनाएँ, जो ड्रॉपडाउनलिस्ट को बाँधने के लिए सूची को लौटाएगा:

public class DropDownData
{
    enum Responses { Yes = 1, No = 2, Maybe = 3 }

    public String Text { get; set; }
    public int Value { get; set; }

    public List<DropDownData> GetList()
    {
        var items = new List<DropDownData>();
        foreach (int value in Enum.GetValues(typeof(Responses)))
        {
            items.Add(new DropDownData
                          {
                              Text = Enum.GetName(typeof (Responses), value),
                              Value = value
                          });
        }
        return items;
    }
}

फिर इस बीओ वर्ग को इंगित करने के लिए ASPX पृष्ठ पर कुछ HTML मार्कअप जोड़ें:

<asp:DropDownList ID="DropDownList1" runat="server" 
    DataSourceID="ObjectDataSource1" DataTextField="Text" DataValueField="Value">
</asp:DropDownList>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" 
    SelectMethod="GetList" TypeName="DropDownData"></asp:ObjectDataSource>

इस विकल्प के लिए किसी कोड की आवश्यकता नहीं है।

DataBind के पीछे कोड

ASPX पृष्ठ में HTML को कम करने के लिए और कोड के पीछे बाइंड करें:

enum Responses { Yes = 1, No = 2, Maybe = 3 }

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        foreach (int value in Enum.GetValues(typeof(Responses)))
        {
            DropDownList1.Items.Add(new ListItem(Enum.GetName(typeof(Responses), value), value.ToString()));
        }
    }
}

वैसे भी, चाल के लिए Enum प्रकार तरीके GetValues, GetNames आदि को आपके लिए काम करने देना है।


6

मुझे यकीन नहीं है कि इसे ASP.NET में कैसे किया जाए लेकिन इस पोस्ट को देखें ... यह मदद कर सकता है?

Enum.GetValues(typeof(Response));

6

आप linq का उपयोग कर सकते हैं:

var responseTypes= Enum.GetNames(typeof(Response)).Select(x => new { text = x, value = (int)Enum.Parse(typeof(Response), x) });
    DropDownList.DataSource = responseTypes;
    DropDownList.DataTextField = "text";
    DropDownList.DataValueField = "value";
    DropDownList.DataBind();

5
Array itemValues = Enum.GetValues(typeof(TaskStatus));
Array itemNames = Enum.GetNames(typeof(TaskStatus));

for (int i = 0; i <= itemNames.Length; i++)
{
    ListItem item = new ListItem(itemNames.GetValue(i).ToString(),
    itemValues.GetValue(i).ToString());
    ddlStatus.Items.Add(item);
}


3

जेनेरिक कोड उत्तर छह का उपयोग करना।

public static void BindControlToEnum(DataBoundControl ControlToBind, Type type)
{
    //ListControl

    if (type == null)
        throw new ArgumentNullException("type");
    else if (ControlToBind==null )
        throw new ArgumentNullException("ControlToBind");
    if (!type.IsEnum)
        throw new ArgumentException("Only enumeration type is expected.");

    Dictionary<int, string> pairs = new Dictionary<int, string>();

    foreach (int i in Enum.GetValues(type))
    {
        pairs.Add(i, Enum.GetName(type, i));
    }
    ControlToBind.DataSource = pairs;
    ListControl lstControl = ControlToBind as ListControl;
    if (lstControl != null)
    {
        lstControl.DataTextField = "Value";
        lstControl.DataValueField = "Key";
    }
    ControlToBind.DataBind();

}

3

इस उत्तर को खोजने के बाद मुझे लगता है कि मुझे लगता है कि ऐसा करने का एक बेहतर (कम से कम अधिक सुरुचिपूर्ण) तरीका है, मैंने सोचा कि मैं वापस आऊंगा और यहां साझा करूंगा।

Page_Load:

DropDownList1.DataSource = Enum.GetValues(typeof(Response));
DropDownList1.DataBind();

LoadValues:

Response rIn = Response.Maybe;
DropDownList1.Text = rIn.ToString();

SaveValues:

Response rOut = (Response) Enum.Parse(typeof(Response), DropDownList1.Text);

2

यह शायद एक पुराना सवाल है .. लेकिन यह मैंने कैसे किया।

नमूना:

public class YourEntity
{
   public int ID { get; set; }
   public string Name{ get; set; }
   public string Description { get; set; }
   public OptionType Types { get; set; }
}

public enum OptionType
{
    Unknown,
    Option1, 
    Option2,
    Option3
}

फिर व्यू में: यहां बताया गया है कि ड्रॉपडाउन का उपयोग कैसे करें।

@Html.EnumDropDownListFor(model => model.Types, htmlAttributes: new { @class = "form-control" })

यह आपकी enum सूची में सब कुछ आबाद करना चाहिए। उम्मीद है की यह मदद करेगा..


यह तब भी काम करता है, अगर आपको रिक्त स्थान के साथ स्ट्रिंग शाब्दिकों को शामिल करना है, तो आपको एक विस्तार वर्ग की आवश्यकता है।

1
यह सबसे अच्छा जवाब है। @ निकुल, आपको विस्तार वर्ग की आवश्यकता नहीं है। आपको केवल एनोटेशन का उपयोग करने की आवश्यकता है। [Display(Name = "Option number one")] Option1,
जूल


1

क्यों इस तरह का उपयोग करने के लिए हर सूची पारित करने में सक्षम नहीं है


public static void BindToEnum(Type enumType, ListControl lc)
        {
            // get the names from the enumeration
            string[] names = Enum.GetNames(enumType);
            // get the values from the enumeration
            Array values = Enum.GetValues(enumType);
            // turn it into a hash table
            Hashtable ht = new Hashtable();
            for (int i = 0; i < names.Length; i++)
                // note the cast to integer here is important
                // otherwise we'll just get the enum string back again
                ht.Add(names[i], (int)values.GetValue(i));
            // return the dictionary to be bound to
            lc.DataSource = ht;
            lc.DataTextField = "Key";
            lc.DataValueField = "Value";
            lc.DataBind();
        }
और उपयोग केवल उतना ही सरल है:

BindToEnum(typeof(NewsType), DropDownList1);
BindToEnum(typeof(NewsType), CheckBoxList1);
BindToEnum(typeof(NewsType), RadoBuuttonList1);


1

ASP.NET तब से कुछ और कार्यक्षमता के साथ अद्यतन किया गया है, और अब आप ड्रॉप-डाउन में अंतर्निर्मित इनम का उपयोग कर सकते हैं।

यदि आप Enum पर खुद को बांधना चाहते हैं, तो इसका उपयोग करें:

@Html.DropDownList("response", EnumHelper.GetSelectList(typeof(Response)))

यदि आप प्रतिसाद के एक उदाहरण पर बाध्यकारी हैं, तो इसका उपयोग करें:

// Assuming Model.Response is an instance of Response
@Html.EnumDropDownListFor(m => m.Response)

0

यह लाइनक्यू का उपयोग कर ड्रॉपडाउन करने के लिए ऑर्डर एन एनम और डेटाबिंड (पाठ और मूल्य) के लिए मेरा समाधान है

var mylist = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().ToList<MyEnum>().OrderBy(l => l.ToString());
foreach (MyEnum item in mylist)
    ddlDivisao.Items.Add(new ListItem(item.ToString(), ((int)item).ToString()));


0

यदि आप अपने कॉम्बो बॉक्स (या अन्य नियंत्रण) में अधिक उपयोगकर्ता के अनुकूल विवरण रखना चाहते हैं, तो आप निम्नलिखित फ़ंक्शन के साथ विवरण विशेषता का उपयोग कर सकते हैं:

    public static object GetEnumDescriptions(Type enumType)
    {
        var list = new List<KeyValuePair<Enum, string>>();
        foreach (Enum value in Enum.GetValues(enumType))
        {
            string description = value.ToString();
            FieldInfo fieldInfo = value.GetType().GetField(description);
            var attribute = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false).First();
            if (attribute != null)
            {
                description = (attribute as DescriptionAttribute).Description;
            }
            list.Add(new KeyValuePair<Enum, string>(value, description));
        }
        return list;
    }

यहाँ वर्णन विशेषताओं के साथ एक एनुम का उदाहरण दिया गया है:

    enum SampleEnum
    {
        NormalNoSpaces,
        [Description("Description With Spaces")]
        DescriptionWithSpaces,
        [Description("50%")]
        Percent_50,
    }

फिर बिंदू को ऐसे करें काबू ...

        m_Combo_Sample.DataSource = GetEnumDescriptions(typeof(SampleEnum));
        m_Combo_Sample.DisplayMember = "Value";
        m_Combo_Sample.ValueMember = "Key";

इस तरह आप बिना ड्रॉपडाउन के जो भी पाठ चाहते हैं, उसे एक चर नाम की तरह देख सकते हैं


0

आप एक्सटेंशन विधियों का भी उपयोग कर सकते हैं। एक्सटेंशन वाले पारिवारिक लोगों के लिए मैं VB और C # प्रलेखन की जाँच करने का सुझाव देता हूं ।


VB एक्सटेंशन:

Namespace CustomExtensions
    Public Module ListItemCollectionExtension

        <Runtime.CompilerServices.Extension()> _
        Public Sub AddEnum(Of TEnum As Structure)(items As System.Web.UI.WebControls.ListItemCollection)
            Dim enumerationType As System.Type = GetType(TEnum)
            Dim enumUnderType As System.Type = System.Enum.GetUnderlyingType(enumType)

            If Not enumerationType.IsEnum Then Throw New ArgumentException("Enumeration type is expected.")

            Dim enumTypeNames() As String = System.Enum.GetNames(enumerationType)
            Dim enumTypeValues() As TEnum = System.Enum.GetValues(enumerationType)

            For i = 0 To enumTypeNames.Length - 1
                items.Add(New System.Web.UI.WebControls.ListItem(saveResponseTypeNames(i), TryCast(enumTypeValues(i), System.Enum).ToString("d")))
            Next
        End Sub
    End Module
End Namespace

एक्सटेंशन का उपयोग करने के लिए:

Imports <projectName>.CustomExtensions.ListItemCollectionExtension

...

yourDropDownList.Items.AddEnum(Of EnumType)()

C # एक्सटेंशन:

namespace CustomExtensions
{
    public static class ListItemCollectionExtension
    {
        public static void AddEnum<TEnum>(this System.Web.UI.WebControls.ListItemCollection items) where TEnum : struct
        {
            System.Type enumType = typeof(TEnum);
            System.Type enumUnderType = System.Enum.GetUnderlyingType(enumType);

            if (!enumType.IsEnum) throw new Exception("Enumeration type is expected.");

            string[] enumTypeNames = System.Enum.GetNames(enumType);
            TEnum[] enumTypeValues = (TEnum[])System.Enum.GetValues(enumType);

            for (int i = 0; i < enumTypeValues.Length; i++)
            {
                items.add(new System.Web.UI.WebControls.ListItem(enumTypeNames[i], (enumTypeValues[i] as System.Enum).ToString("d")));
            }
        }
    }
}

एक्सटेंशन का उपयोग करने के लिए:

using CustomExtensions.ListItemCollectionExtension;

...

yourDropDownList.Items.AddEnum<EnumType>()

यदि आप एक ही समय में चयनित आइटम को प्रतिस्थापित करना चाहते हैं

items.Add(New System.Web.UI.WebControls.ListItem(saveResponseTypeNames(i), saveResponseTypeValues(i).ToString("d")))

साथ में

Dim newListItem As System.Web.UI.WebControls.ListItem
newListItem = New System.Web.UI.WebControls.ListItem(enumTypeNames(i), Convert.ChangeType(enumTypeValues(i), enumUnderType).ToString())
newListItem.Selected = If(EqualityComparer(Of TEnum).Default.Equals(selected, saveResponseTypeValues(i)), True, False)
items.Add(newListItem)

System.Enum में कनवर्ट करके, फिर int आकार और आउटपुट समस्याओं से बचा जाता है। उदाहरण के लिए 0xFFFF0000 एक यूइंट के रूप में 4294901760 होगा लेकिन एक इंट के रूप में -65536 होगा।

TryCast और System.Enum Convert.ChangeType (enumTypeValues ​​[i], enumUnderType) .ToString () (मेरी गति परीक्षण में 12:13) की तुलना में थोड़ा तेज़ है।



0

स्वीकृत समाधान काम नहीं करता है, लेकिन नीचे दिए गए कोड से दूसरों को सबसे छोटा समाधान ढूंढने में मदद मिलेगी।

 foreach (string value in Enum.GetNames(typeof(Response)))
                    ddlResponse.Items.Add(new ListItem()
                    {
                        Text = value,
                        Value = ((int)Enum.Parse(typeof(Response), value)).ToString()
                    });

0

आप इसे बहुत कम कर सकते हैं

public enum Test
    {
        Test1 = 1,
        Test2 = 2,
        Test3 = 3
    }
    class Program
    {
        static void Main(string[] args)
        {

            var items = Enum.GetValues(typeof(Test));

            foreach (var item in items)
            {
                //Gives you the names
                Console.WriteLine(item);
            }


            foreach(var item in (Test[])items)
            {
                // Gives you the numbers
                Console.WriteLine((int)item);
            }
        }
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.