2010-08-07 20 views
19

मैं enums के लिए एक डिफ़ॉल्ट संपादक टेम्पलेट कैसे बना सकता हूं? जो से मेरा मतलब है: मैं कुछ इस तरह कर सकते हैं:enums के लिए एक डिफ़ॉल्ट संपादक टेम्पलेट कैसे बनाएँ?

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Enum>" %> 
<% -- any code to read the enum and write a dropdown --> 

और नाम Enum.ascx तहत EditorTemplates फ़ोल्डर में डाल?

मेरी समस्या के लिए यहां एक कामकाज है जिसकी मैंने कोशिश की, लेकिन मुझे इसकी आवश्यकता नहीं है।

public enum GenderEnum 
{ 
    /// <summary> 
    /// Male 
    /// </summary> 
    [Description("Male Person")] 
    Male, 

    /// <summary> 
    /// Female 
    /// </summary> 
    [Description("Female Person")] 
    Female 
} 

मैं GenderEnum.acsx नामक एक टेम्पलेट बना दिया है और Shared/EditorTemplates फ़ोल्डर में रख:

यहाँ मेरी Enum है।

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<AlefTech.HumanResource.Core.GenderEnum>" %> 
<%@ Import Namespace="AlefTech.HumanResource.WebModule.Classes" %> 
<%=Html.DropDownListFor(m => m.GetType().Name, Model.GetType()) %> 

बेशक विधि अपने ही है:

public static class HtmlHelperExtension 
    { 
     public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type enumType) 
     { 
      List<SelectListItem> list = new List<SelectListItem>(); 
      Dictionary<string, string> enumItems = enumType.GetDescription(); 
      foreach (KeyValuePair<string, string> pair in enumItems) 
       list.Add(new SelectListItem() { Value = pair.Key, Text = pair.Value }); 
      return htmlHelper.DropDownListFor(expression, list); 
     } 

     /// <summary> 
     /// return the items of enum paired with its descrtioption. 
     /// </summary> 
     /// <param name="enumeration">enumeration type to be processed.</param> 
     /// <returns></returns> 
     public static Dictionary<string, string> GetDescription(this Type enumeration) 
     { 
      if (!enumeration.IsEnum) 
      { 
       throw new ArgumentException("passed type must be of Enum type", "enumerationValue"); 
      } 

      Dictionary<string, string> descriptions = new Dictionary<string, string>(); 
      var members = enumeration.GetMembers().Where(m => m.MemberType == MemberTypes.Field); 

      foreach (MemberInfo member in members) 
      { 
       var attrs = member.GetCustomAttributes(typeof(DescriptionAttribute), false); 
       if (attrs.Count() != 0) 
        descriptions.Add(member.Name, ((DescriptionAttribute)attrs[0]).Description); 
      } 
      return descriptions; 
     } 

    } 

हालांकि भले ही यह मेरे लिए काम किया, है, यह मैं क्या पूछ रहा हूँ नहीं है यहाँ खाका है।

कोड Shared\EditorTemplates\Enum.acsx के लिए: इसके बजाय, मैं काम करने के लिए निम्नलिखित की जरूरत है

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Enum>" %> 
<%@ Import Namespace="System.Web.Mvc.Html" %> 
<%@ Import Namespace="WhereMyExtentionMethod" %> 
<%=Html.DropDownListFor(m => m.GetType().Name, Model.GetType()) %> 

इस के साथ मैं हर किसी भी अधिक enum के लिए खाका बनाने के लिए नहीं होगा।

+0

क्या आपको अभी भी यह काम करने के लिए नहीं मिला? क्या आप यहां इस्तेमाल किए गए सहायक के लिए कोड पोस्ट करना चाहते हैं: htmlHelper.DropDownListFor (अभिव्यक्ति, सूची) ;? –

+0

वैसे, यदि आप अपने मॉडल में अपने enum-field पर [UIHint ("Enum") डालते हैं, तो आपके कोड को काम करना चाहिए, सिस्टम.Web.Mvc.ViewUserControl को डायनामिक में बदलें, और उन्हें सही प्रकार के रूप में डालें सहायक कॉल में :) –

उत्तर

7

आप सभी अपने योगदान के लिए धन्यवाद
Yngvebn, मैं अपने समाधान (अपने पिछले टिप्पणी में) की कोशिश की पहले, लेकिन केवल एक चीज मैं नहीं किया <dynamic> है, मैं सामान्य प्रकार में बजाय <Enum> इस्तेमाल किया।

में पिछले समाधान है:
Enum.acsx नामक एक टेम्पलेट बना सकते हैं और नीचे दृश्य डाल दिया \ साझा \ EditorTemplates

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<dynamic>" %> 
<%@ Import Namespace="System.Web.Mvc.Html" %> 
<%@ Import Namespace="the extension methods namespace" %> 
<% Enum model = (Enum)Model; %> 
<%=Html.DropDownList(model.GetType().Name,model.GetType())%> 

और अपने इकाई में:

public class Person 
{ 
    [UIHint("Enum")] 
    public GenderEnum Gender{get;set;} 
} 

public Enum GenderEnum 
{ 
[Description("Male Person")] 
Male, 
[Description("Female Person")] 
Female 
} 

और फिर विस्तार विधि हैं:

public static class HtmlHelperExtension 
    { 
     public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type enumType) 
     { 
      List<SelectListItem> list = new List<SelectListItem>(); 
      Dictionary<string, string> enumItems = enumType.GetDescription(); 
      foreach (KeyValuePair<string, string> pair in enumItems) 
       list.Add(new SelectListItem() { Value = pair.Key, Text = pair.Value }); 
      return htmlHelper.DropDownListFor(expression, list); 
     } 

     /// <summary> 
     /// return the items of enum paired with its descrtioption. 
     /// </summary> 
     /// <param name="enumeration">enumeration type to be processed.</param> 
     /// <returns></returns> 
     public static Dictionary<string, string> GetDescription(this Type enumeration) 
     { 
      if (!enumeration.IsEnum) 
      { 
       throw new ArgumentException("passed type must be of Enum type", "enumerationValue"); 
      } 

      Dictionary<string, string> descriptions = new Dictionary<string, string>(); 
      var members = enumeration.GetMembers().Where(m => m.MemberType == MemberTypes.Field); 

      foreach (MemberInfo member in members) 
      { 
       var attrs = member.GetCustomAttributes(typeof(DescriptionAttribute), false); 
       if (attrs.Count() != 0) 
        descriptions.Add(member.Name, ((DescriptionAttribute)attrs[0]).Description); 
      } 
      return descriptions; 
     } 

    } 
+1

क्या आपने वास्तव में इस समाधान की कोशिश की है? संकलन समय त्रुटियां –

+0

बेशक हैं, विन्स मैंने कोशिश की, आप किस तरह की संकलन त्रुटियों का मतलब है ?? ... अगर आप चाहें तो यहां पोस्ट करें, मैं आपकी मदद कर सकता हूं। –

+0

मैं इसे देख रहा था और आपको DropDownFor के लिए कोड जोड़ा गया था और ड्रॉपडाउन का उपयोग करके अपना उदाहरण दिया, यह समस्या है। मैं एक बी भी इसे फेंक दिया गया था। – efbenson

0

हाँ

लगभग सुनिश्चित करें कि यह बॉक्स से बाहर काम करता है।


अपने टेम्पलेट को अपने नाम के समान नाम देने का प्रयास करें।

+0

वास्तव में मैंने ऐसा किया, लेकिन यह काम नहीं किया। मैंने यह फ़ाइल बनाई है, लेकिन फ़ाइल को कभी नहीं कहा जाता है। मुझे लगता है कि प्रॉपम (एनम) एक प्रकार नहीं है? –

+0

अच्छी तरह से, मैं क्या करने की कोशिश कर रहा हूं, मेरे समाधान में सभी घोषित एनम के लिए एक फ़ाइल बनाना है। जैसे कि मैंने (int) के लिए एक डिफ़ॉल्ट संपादक टेम्पलेट बनाया है, इसलिए जब भी (int) की कोई संपत्ति हो, तो एमवीसी उस टेम्पलेट का उपयोग करेगा। आपके द्वारा सुझाए गए समाधान ने मुझे अपनी परियोजना में प्रत्येक प्रकार के enum के लिए एक टेम्पलेट बनाने के लिए बनाया है। –

1

मुझे नहीं लगता कि सभी enum प्रकारों के लिए एक संपादक को परिभाषित करने का एक डिफ़ॉल्ट तरीका है क्योंकि आप स्थिति के आधार पर अलग-अलग व्यवहार चाहते हैं। उदाहरण के लिए, हो सकता है कि आपके पास एक [ध्वज] enum हो और बहु ​​चयन चाहते हों, या आप ड्रॉपडाउन सूची चाहते हैं, या आप रेडियो बटन चाहते हैं।

प्लस, आम तौर पर आप परिवर्तनीय नामकरण सीमाओं में जो कुछ भी हासिल कर सकते हैं उससे परे कुछ प्रकार की सार्थक प्रदर्शन स्ट्रिंग चाहते हैं।

निश्चित रूप से प्रकार enum के एक संपत्ति को बताए तरीके से काम करता है, लेकिन तुम कैसे मिलता है कि मूल्य आप पर निर्भर होने जा रहा है।

5

यहाँ एक सहायक मैं इस के लिए बनाया है .. आपके विचार में आप बस कर सकते हैं:

<%= Html.DropDownForEnum<MyEnum>("some-name-for-dropdown", MyEnum.TheFirstValue) %> 

वास्तविक लटकती में पाठ यह संसाधन फ़ाइल से मेल खाता है में एक संसाधन के लिए दिखेगा के लिए enum का नाम, अन्यथा केवल वास्तविक Enumtext लिखो।

public static MvcHtmlString DropDownForEnum<T>(this HtmlHelper h, string name, T selectedValue) 
{ 
    Type enumType = typeof(T); 
    Tag t = new Tag("select").With("name", name).And("id", name); 

    foreach (T val in Enum.GetValues(enumType)) 
    { 
     string enumText = Resources.ResourceManager.GetString(val.ToString()); 
     if (String.IsNullOrEmpty(enumText)) enumText = val.ToString(); 
     Tag option = new Tag("option").With("value", (val).ToString()).AndIf(val.Equals(selectedValue), "selected", "selected").WithText(enumText); 
     t.Append(option); 
    } 
    return MvcHtmlString.Create(t.ToString()); 
} 

तुम भी मेरी अतिभारित टैग श्रेणी की जरूरत है अगर आप इसे कोई नए सिरे से लिखना के साथ काम करना चाहता हूँ होगा ..

public class Tag : TagBuilder 
{ 
public Tag (string TagName): base(TagName) 
{ 

} 

public Tag Append(Tag innerTag) 
{ 
    base.InnerHtml += innerTag.ToString(); 
    return this; 
} 

public Tag WithText(string text) 
{ 

    base.InnerHtml += text; 
    return this; 
} 

public Tag With(Tag innerTag) 
{ 
    base.InnerHtml = innerTag.ToString(); 
    return this; 
} 

public Tag With(string attributeName, string attributeValue) 
{ 
    base.Attributes.Add(attributeName, attributeValue); 
    return this; 
} 

public Tag And(string attributeName, string attributeValue) 
{ 
    base.Attributes.Add(attributeName, attributeValue); 
    return this; 
} 


public Tag AndIf(bool condition, string attributeName, string attributeValue) 
{ 
    if(condition) 
     base.Attributes.Add(attributeName, attributeValue); 
    return this; 
} 
} 
+0

जो महान Yngvebn है, लेकिन यह अभी भी मेरे प्रश्न का उत्तर नहीं दे रहा है। असल में, मेरी समस्या के आसपास काम करने के लिए, मैंने आपके कोड के समान कुछ बनाया है, लेकिन मैं संसाधनों का उपयोग नहीं कर रहा हूं, इसके बजाय मैं अपने एनम के प्रत्येक तत्व पर विवरण विशेषता का उपयोग कर रहा हूं। मैं एक उत्तर जोड़ूंगा जिसमें मेरा कोड शामिल है। –

5

नोर सबनी, मैंने संसाधनों के साथ स्थानीयकरण का समर्थन करने के लिए आपके संस्करण को संशोधित किया। इसलिए मैं इस तरह देखने के लिए अब DataAnnotations नाम स्थान

public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type enumType) 
    { 
     List<SelectListItem> list = new List<SelectListItem>(); 
     Dictionary<string, string> enumItems = enumType.GetDisplayNames(htmlHelper.ViewContext.HttpContext); 
     foreach (KeyValuePair<string, string> pair in enumItems) 
      list.Add(new SelectListItem() { Value = pair.Key, Text = pair.Value }); 
     return htmlHelper.DropDownListFor(expression, list); 
    } 

    /// <summary> 
    /// return the items of enum paired with its DisplayName. 
    /// </summary> 
    /// <param name="enumeration">enumeration type to be processed.</param> 
    /// <returns></returns> 
    public static Dictionary<string, string> GetDisplayNames(this Type enumeration, HttpContextBase httpContext) 
    { 
     if (!enumeration.IsEnum) 
     { 
      throw new ArgumentException("passed type must be of Enum type", "enumerationValue"); 
     } 

     Dictionary<string, string> displayNames = new Dictionary<string, string>(); 
     var members = enumeration.GetMembers().Where(m => m.MemberType == MemberTypes.Field); 

     foreach (MemberInfo member in members) 
     { 
      var attrs = member.GetCustomAttributes(typeof(DisplayAttribute), false); 
      if (attrs.Count() != 0) 
       if (((DisplayAttribute)attrs[0]).ResourceType != null) 
       { 
        displayNames.Add(member.Name, ((DisplayAttribute)attrs[0]).GetName();); 
       } 
       else 
       { 
        displayNames.Add(member.Name, ((DisplayAttribute)attrs[0]).Name); 
       } 
     } 
     return displayNames; 
    } 

एक enum की परिभाषा है की DisplayAttribute को DescriptionAttribute बदल दिया है:

public enum Gender 
{ 
    [Display(Name = "Male", ResourceType = typeof(mynamespace.App_LocalResources.Shared))] 
    Male = 1, 

    [Display(Name = "Female", ResourceType = typeof(mynamespace.App_LocalResources.Shared))] 
    Female = 2, 

} 

यह उसी तरह से एक दृश्य में इस्तेमाल किया जा सकता, जैसे (रेजर):

@Html.DropDownListFor(model => model.Gender, typeof(Gender)) 

आशा है कि इससे किसी की मदद मिलेगी!

2

मैं dropdownlistfor विधि थोड़ा आसान बना दिया है और अब आप इसके साथ एक selectedValue दे सकते हैं:

public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type enumType) 
{ 
    return DropDownListFor(htmlHelper, expression, enumType, null); 
} 

public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type enumType, object selectedValue) 
{ 
    Dictionary<string, string> enumItems = enumType.GetDisplayNames(htmlHelper.ViewContext.HttpContext); 
    return htmlHelper.DropDownListFor(expression, new SelectList(enumItems, "Key", "Value", selectedValue)); 
} 

अपने दृश्य में इस तरह का उपयोग करें:

@Html.DropDownListFor(m => m.Gender, typeof(Gender), Model.Gender) 

मॉडल मेरी MVC मॉडल और है इसकी संपत्ति लिंग में DropDownListFor के लिए चयनित वैल्यू शामिल है।

17

उत्तर देने के लिए देर हो गई लेकिन मुझे आशा है कि इससे दूसरों की मदद मिलेगी। आदर्श रूप में आप सभी enums, सम्मेलन द्वारा अपने Enum टेम्पलेट का उपयोग करने के लिए एक UIHint हर बार निर्दिष्ट करके नहीं चाहते हैं, और आप इस तरह कस्टम मॉडल मेटाडाटा प्रदाता बनाने के द्वारा कि पूरा कर सकते हैं:

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

public class CustomMetadataProvider : DataAnnotationsModelMetadataProvider 
{ 
    protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName) { 
     var mm = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName); 
     if (modelType.IsEnum && mm.TemplateHint == null) { 
      mm.TemplateHint = "Enum"; 
     } 
     return mm; 
    } 
} 

तो बस इसे Application_Start में रजिस्टर Global.asax.cs की विधि:

ModelMetadataProviders.Current = new CustomMetadataProvider(); 

अब आपके सभी enum गुण डिफ़ॉल्ट रूप से आपके एनम टेम्पलेट का उपयोग करेंगे।

+0

शानदार! अच्छा विचार। –

+0

मैं http://odetocode.com/blogs/scott/archive/2012/09/04/working-with-enums-and-templates-in-asp-net-mvc.aspx यही से कुछ मदद के साथ अपने विचार का उपयोग किया पूरी तरह से ठीक काम किया। धन्यवाद ;) –

1

आप इस उदाहरण का उपयोग कर सकते .....

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace Profile.Data.Enum 
{ 
    public enum EfficiencyType 
    { 
     Good = 1, 
     Excelent = 2, 
     Better = 3 
    } 
} 

विस्तार विधि है ....

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

namespace Profile.Web.HtmlHelper 
{ 
    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 है ....

@Html.DropDownListFor(model => model.EfficiencyType, new SelectList(Enum.GetValues(typeof(EfficiencyType)), Model.EfficiencyType), "--Select--") 
संबंधित मुद्दे