惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
Google Developers Blog
WordPress大学
WordPress大学
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
小众软件
小众软件
人人都是产品经理
人人都是产品经理
美团技术团队
Blog — PlanetScale
Blog — PlanetScale
S
SegmentFault 最新的问题
博客园 - 【当耐特】
V
V2EX
Microsoft Azure Blog
Microsoft Azure Blog
博客园 - 叶小钗
Google DeepMind News
Google DeepMind News
量子位
罗磊的独立博客
月光博客
月光博客
N
Netflix TechBlog - Medium
大猫的无限游戏
大猫的无限游戏
博客园_首页
P
Proofpoint News Feed
Jina AI
Jina AI
云风的 BLOG
云风的 BLOG
博客园 - 司徒正美
腾讯CDC

博客园 - 王继坤

DataTable 递归 简单的程序,来实现无限级列表 结合 jquery.table.js 实现 asp.net mvc 2 简简单单做开发 使用DataContext扩展方法Find<TEntity>(TEntity obj) 遇到的问题 asp.net mvc 2 简简单单做开发 实现基本数据操作操作RepositoryController<T> asp.net mvc 2 简简单单做开发 自定义Controller基类 - 王继坤 asp.net mvc 2 简简单单做开发 通用增删改基本操作通用页面 asp.net mvc 2 DisplayTemplates 的使用 FcDigg 源码 asp.net 3.5 linq to sql 扩展方法 linq to access 简单实现 实例demo linq to access 简单实现 asp.net mvc 随想 asp.net mvc ajax实现1 asp.net ajax fccms 小型简单个人blog源码 FCKEDITOR中文使用说明 js调用 dotfuscator.exe 采用线程生成静态页面 新的开始--- gridview 实现多字段综合查询
asp.net mvc 2 简简单单做开发 自定义DropdownList控件
王继坤 · 2010-07-03 · via 博客园 - 王继坤

  asp.net mvc 2 给我们提供了强大的自定义功能,今天主要说下DropdownList自定义绑定字段显示,通过ViewData设定DropdownList的数据项。自动绑定显示。实现的方式。在global.asax 中注册 FieldTemplateMetadataProvider,

 ModelMetadataProviders.Current = new mvc.Models.FieldTemplateMetadataProvider();
通过返回的 FieldTemplateMetadata 。在MetaData中指定使用DropDownList的字段
       [Display( Name="",Order=12)]
        [Required]
        [SearchFilter]
        [DisplayName("栏目")]
        [DropDownList("Category""Id""Name")]
        public int Cid { getset; }

通过DropDownList指定调用的模板为dropdownlist.ascx ,在dropdownlist.ascx 将默认的 ModelMetadata 转成FieldTemplateMetadata 获取 DropDownListAttribute 。

<script runat="server">
    DropDownListAttribute GetDropDownListAttribute()
    {
        FieldTemplateMetadata metaData = ViewData.ModelMetadata as FieldTemplateMetadata;

        return (metaData != null) ? metaData.Attributes.OfType<DropDownListAttribute>().SingleOrDefault() : null;
    }
</script>

 
  通过DropDownListAttribute 获得 ViewData的key ,绑定的文本对应的字段,值对应的字段,使用html.DropDownlist显示数据

    DropdownList.ascx 代码

代码

<%@ Import Namespace="mvc.Models"%>
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<script runat="server">
    DropDownListAttribute GetDropDownListAttribute()
    {
        FieldTemplateMetadata metaData 
= ViewData.ModelMetadata as FieldTemplateMetadata;return (metaData != null? metaData.Attributes.OfType<DropDownListAttribute>().SingleOrDefault() : null;
    }
</script>
<% DropDownListAttribute attribute = GetDropDownListAttribute();%>
<% if (attribute != null) {%>
    
<%= Html.DropDownList(string.Empty, new SelectList(ViewData[attribute.ViewDataKey] as IEnumerable, attribute.DataValueField, attribute.DataTextField, Model), attribute.OptionLabel, attribute.HtmlAttributes) %>
<% }%>
<% else {%>
    
<%= Html.DisplayForModel() %>
<% }%>

自定义DropDownListAttribute 属性

代码

namespace mvc.Models
{
    
using System;
    
using System.Collections.Generic;
    
using System.ComponentModel;
    
using System.ComponentModel.DataAnnotations;
    
using System.Linq;
    
using System.Web.Routing;

    [AttributeUsage(AttributeTargets.Property, AllowMultiple 

= false, Inherited = true)]
    
public sealed class DropDownListAttribute : Attribute, ITemplateField
    {
        
private static string defaultTemplateName;public DropDownListAttribute(string viewDataKey, string dataValueField) : this(viewDataKey, dataValueField, null)
        {
        }
public DropDownListAttribute(string viewDataKey, string dataValueField, string dataTextField) : this(viewDataKey, dataValueField, dataTextField, null)
        {
        }
public DropDownListAttribute(string viewDataKey, string dataValueField, string dataTextField, string optionLabel) : this(DefaultTemplateName, viewDataKey, dataValueField, dataTextField, optionLabel, null)
        {
        }
public DropDownListAttribute(string viewDataKey, string dataValueField, string dataTextField, string optionLabel, object htmlAttributes) : this(DefaultTemplateName, viewDataKey, dataValueField, dataTextField, optionLabel, htmlAttributes)
        {
        }
public DropDownListAttribute(string templateName, string viewDataKey, string dataValueField, string dataTextField, string optionLabel, object htmlAttributes)
        {
            
if (string.IsNullOrEmpty(templateName))
            {
                
throw new ArgumentException("Template name cannot be empty.");
            }
if (string.IsNullOrEmpty(viewDataKey))
            {
                
throw new ArgumentException("View data key cannot be empty.");
            }
if (string.IsNullOrEmpty(dataValueField))
            {
                
throw new ArgumentException("Data value field cannot be empty.");
            }

            TemplateName 

= templateName;
            ViewDataKey 
= viewDataKey;
            DataValueField 
= dataValueField;
            DataTextField 
= dataTextField;
            OptionLabel 
= optionLabel;
            HtmlAttributes 
= new RouteValueDictionary(htmlAttributes);
        }
public static string DefaultTemplateName
        {
            
get
            {
                
if (string.IsNullOrEmpty(defaultTemplateName))
                {
                    defaultTemplateName 
= "DropDownList";
                }
return defaultTemplateName;
            }
            
set
            {
                defaultTemplateName 
= value;
            }
        }
public string TemplateName { getprivate set; }public string ViewDataKey { getprivate set; }public string DataValueField { getprivate set; }public string DataTextField { getprivate set; }public string OptionLabel { getprivate set; }public IDictionary<stringobject> HtmlAttributes { getprivate set; }public object GetSelectedValue(object model)
        {
            
return GetPropertyValue(model, DataValueField);
        }
public object GetSelectedText(object model)
        {
            
return GetPropertyValue(model, !string.IsNullOrEmpty(DataTextField) ? DataTextField : DataValueField);
        }
private static object GetPropertyValue(object model, string propertyName)
        {
            
if (model != null)
            {
                PropertyDescriptor property 
= GetTypeDescriptor(model.GetType()).GetProperties()
                                                                                .Cast
<PropertyDescriptor>()
                                                                                .SingleOrDefault(p 
=> string.Compare(p.Name, propertyName, StringComparison.OrdinalIgnoreCase) == 0);
               
                
if (property != null)
                {
                    
return property.GetValue(model);
                }
            }
return null;
        }
private static ICustomTypeDescriptor GetTypeDescriptor(Type type)
        {
            
return new AssociatedMetadataTypeTypeDescriptionProvider(type).GetTypeDescriptor(type);
        }
    }
}

自定义DataAnnotationsModelMetadata

代码

public class FieldTemplateMetadata : DataAnnotationsModelMetadata
    {
        
public FieldTemplateMetadata(DisplayAttribute aa, DataAnnotationsModelMetadataProvider provider, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName, DisplayColumnAttribute displayColumnAttribute, IEnumerable<Attribute> attributes) : base(provider, containerType, modelAccessor, modelType, propertyName, displayColumnAttribute)
        {
            Attributes 
= new List<Attribute>(attributes);
            Display 
= aa;
        }
public IList<Attribute> Attributes
        {
            
get;
            
private set;
        }
        
public DisplayAttribute Display { getset; }
    }

自定义 DataAnnotationsModelMetadataProvider

代码

public class FieldTemplateMetadataProvider : DataAnnotationsModelMetadataProvider
    {
        
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
        {
            DataAnnotationsModelMetadata result 
= (DataAnnotationsModelMetadata) base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);string templateName = attributes.OfType<ITemplateField>()
                                            .Select(field 
=> field.TemplateName)
                                            .LastOrDefault();
            List
<System.Attribute> attributeList = new List<System.Attribute>(attributes);
            DisplayAttribute disp 
= attributeList.OfType<DisplayAttribute>().FirstOrDefault();
            
if (disp != null)
            {
                result.ShortDisplayName 
= disp.Order.ToString(); ;
                result.Description 
= disp.Description;
            }

            var data

= (new FieldTemplateMetadata(disp, this, containerType, modelAccessor, modelType, propertyName, attributes.OfType<DisplayColumnAttribute>().FirstOrDefault(), attributes)

                    {
                        TemplateHint 

= !string.IsNullOrEmpty(templateName) ? templateName : result.TemplateHint,
                        HideSurroundingHtml 
= result.HideSurroundingHtml,
                        DataTypeName 
= result.DataTypeName,
                        IsReadOnly 
= result.IsReadOnly,
                        NullDisplayText 
= result.NullDisplayText,
                        DisplayFormatString 
= result.DisplayFormatString,
                        ConvertEmptyStringToNull 
= result.ConvertEmptyStringToNull,
                        EditFormatString 
= result.EditFormatString,
                        ShowForDisplay 
= result.ShowForDisplay,
                        ShowForEdit 
= result.ShowForEdit,
                        DisplayName 
= result.DisplayName,
                        Description 
= result.Description,
                        ShortDisplayName 
= result.ShortDisplayName,

                    });

            SearchFilterAttribute searchFilterAttribute 

= attributes.OfType<SearchFilterAttribute>().FirstOrDefault();
            
if (searchFilterAttribute != null)
            {
                data.AdditionalValues.Add(
"Search", searchFilterAttribute);
            }

            OrderByAttribute orderByAttribute 

= attributes.OfType<OrderByAttribute>().FirstOrDefault();
            
if (orderByAttribute != null)
            {
                data.AdditionalValues.Add(
"OrderBy", orderByAttribute);
            }
            
return data;
        }
    }