• 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;
            }
        }
     
    ------------------------------------------------------------------------------------
    作者:王继坤

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    ------------------------------------------------------------------------------------
  • 相关阅读:
    Linux/Unix中的#!和!#
    包含min函数的栈
    顺时针打印矩阵
    二叉树镜像
    数的子结构
    合并两个排序的链表
    反转链表
    链表中倒数第K个结点
    调整数组顺序使奇数位于偶数前面
    在O(1)时间删除链表结点
  • 原文地址:https://www.cnblogs.com/wangjikun3/p/1770318.html
Copyright © 2020-2023  润新知