Asp.net

如何為枚舉製作預設編輯器模板?

  • August 7, 2010

如何為枚舉創建預設編輯器模板?我的意思是:我可以做這樣的事情:

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

並將其放在名稱下的 EditorTemplates 文件夾中Enum.ascx

這是我嘗試過的問題的解決方法,但這不是我需要的。

這是我的枚舉:

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

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

我製作了一個名為的模板GenderEnum.acsx並將其放入Shared/EditorTemplates文件夾中。這是模板:

<%@ 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()) %>

有了這個,我就不必再為每個枚舉製作模板了。

謝謝大家的貢獻

Yngvebn,我之前嘗試過你的解決方案(在你的最後評論中),但我唯一沒有做的是<dynamic>,我用<Enum>泛型類型代替。

最後的解決方案是:

創建一個名為 Enum.acsx 的模板並將其放在Views\Shared\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;
       }

   }

遲到了,但我希望這對其他人有幫助。理想情況下,您希望所有枚舉都按約定使用您的 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;
   }
}

然後只需在 Global.asax.cs 的 Application_Start 方法中註冊它:

ModelMetadataProviders.Current = new CustomMetadataProvider();

現在您的所有枚舉屬性將預設使用您的枚舉模板。

引用自:https://stackoverflow.com/questions/3431515