asp.net mvc 2 简简单单做开发 自定义DropdownList控件

  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;
        }
    }

 

 

posted @ 2010-07-03 08:37  王继坤  阅读(2846)  评论(5编辑  收藏  举报
我要啦免费统计