zoukankan      html  css  js  c++  java
  • Asp.net 2.0 自定义控件开发专题讲解[为用户控件增加DataSource属性, 能够自动识别不同数据源](示例代码下载)

    (一).  概要

              开发<数据绑定用户控件>, 要实现一个DataSource属性, 并且能够自动识别不同的数据源, 如: ArrayList,

    DataTable, DataSet, XML文件等.

              在书上和网上找了些资料, 它们一般的实现方案是把一些具有DataSource属性的数据控件

    DataList/Reapter等嵌套到用户控件里面实现, 比较容易实现.  但也存在一些问题:

             1. 如果实现很简单的功能, 把一个DataList嵌套在用户控件里面, 有些大才小用, 比较庞大, 产生冗余代码较

                 多, 效率也不会很高.

             2. 缺乏灵活性. 由于嵌套数据绑定控件到用户控件中, 毕竟是"变态"地做法; 这样太依赖现在数据绑定控件,

                 实现某些特殊功能缺乏灵活性, 甚至有些功能受限制而无法实现.

              决定自己写一个.  在用户控件中实现数据源DataSource属性比自定义控件中复杂多了. 自定义控件中, 尤

    其是在 Dot Net 2.0中实现此属性非常简单,  具体是实现 BaseDataBoundControl(数据绑定基类)/

    /DataBoundControl(列表和表格控件基类)和HierarchicalDataBoundControl(开发Tree和Menu基类)等几个

    基类,  再重写几个方法就OK了. 

            但用户控件遇到麻烦, 它默认已经继承了 System.Web.UI.UserControl 用户控件基类, 不能再继承其它

    类了(C#语法规定不允许多继承).   下面这个例子是参考了一个本上的一个自定义控件例子, 修改了一些代码,

    把它改到这个用户控件中了.  网上很难找到用户控件这样的示例, 共享一下.

    控件很简单, 只有DataSource相关的几个属性

    [涉及到公司代码版权问题, 自己单独做了个只有DataSource功能的最简单例子,  文章主旨只讲这个属性] .

    (二). 绑定效果

    (三).  核心代码

    1. 用户控件部分

      1 using System.ComponentModel;
      2 using System.Xml;
      3 using System.Xml.Schema;
      4 using System.Xml.Serialization;
      5 
      6 /// <summary>
      7 /// Author: [ ChengKing(ZhengJian) ] 
      8 /// Blog:   Http://blog.csdn.net/ChengKing
      9 /// </summary>
     10 public partial class LinkList : System.Web.UI.UserControl
     11 {
     12 
     13     private bool blnMultiTypeDataSource = false;
     14 
     15     #region 属性   
     16 
     17 
     18 
     19     /// <summary>
     20     /// 表格每行图像控件的指向图片名称
     21     /// </summary>
     22     [
     23      Bindable(true),
     24      Category("Data"),
     25      DefaultValue(null)
     26     ]
     27     public string DataImageField
     28     {
     29         get
     30         {
     31             String s = (String)ViewState["DataImageField"];
     32             return ((s == null? String.Empty : s);
     33         }
     34 
     35         set
     36         {
     37             ViewState["DataImageField"= value;
     38         }
     39     }
     40 
     41     /// <summary>
     42     /// 表格每行链接控件显示的文本
     43     /// </summary>    
     44     [
     45      Bindable(true),
     46      Category("Data"),
     47      DefaultValue(null)
     48     ]
     49     public string DataTextField
     50     {
     51         get
     52         {
     53             String s = (String)ViewState["DataTextField"];
     54             return ((s == null? String.Empty : s);
     55         }
     56 
     57         set
     58         {
     59             ViewState["DataTextField"= value;
     60         }
     61     }
     62 
     63     /// <summary>
     64     /// 表格第行链接控件的跳转目标页面链接
     65     /// </summary>
     66     [
     67      Bindable(true),
     68      Category("Data"),
     69      DefaultValue(null)
     70     ]
     71     public string DataLinkToField
     72     {
     73         get
     74         {
     75             String s = (String)ViewState["DataLinkToField"];
     76             return ((s == null? String.Empty : s);
     77         }
     78 
     79         set
     80         {
     81             ViewState["DataLinkToField"= value;
     82         }
     83     }
     84 
     85     /// <summary>
     86     /// 表格每行的链接目标页面打开方式
     87     /// </summary>
     88     [
     89      Bindable(true),
     90      Category("Data"),
     91      DefaultValue(null)
     92     ]
     93     public string DataLinkTargetField
     94     {
     95         get
     96         {
     97             String s = (String)ViewState["DataLinkTargetField"];
     98             return ((s == null? String.Empty : s);
     99         }
    100 
    101         set
    102         {
    103             ViewState["DataLinkTargetField"= value;
    104         } 
    105     }
    106 
    107     private object _dataSource;
    108 
    109     [
    110      Bindable(true),     
    111      Category("Data"),
    112      DefaultValue(null),
    113      Description("获取或设置数据源"),
    114      DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
    115     ]
    116     public virtual object DataSource
    117     {
    118         get
    119         {
    120             return _dataSource;
    121         }
    122         set
    123         {
    124             if ((value == null|| (value is IListSource) || (value is IEnumerable))
    125             {
    126                 _dataSource = value;
    127             }
    128             else
    129             {
    130                 throw new ArgumentException();
    131             }
    132         }
    133     }
    134 
    135     [
    136         Category("Data"),
    137         DefaultValue(""),
    138         Description("获取或者设置绑定的数据成员.")
    139     ]
    140     public virtual string DataMember
    141     {
    142         get
    143         {
    144             string s = (string)ViewState["DataMember"];
    145             return (s == null? String.Empty : s;
    146         }
    147         set
    148         {
    149             ViewState["DataMember"= value;
    150         }
    151     }
    152 
    153     [
    154      Bindable(true),
    155      Category("Data"),
    156      DefaultValue(null),
    157      Description("获取或设置XML文件路径"),
    158      DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
    159     ]
    160     public virtual string XMLDataFile
    161     {
    162         get
    163         {
    164             string s = (string)ViewState["XMLDataFile"];
    165             return (s == null? String.Empty : s;
    166         }
    167         set
    168         {
    169             ViewState["XMLDataFile"= value;
    170         }
    171     }
    172 
    173     [
    174          Bindable(true),
    175          Category("Data"),
    176          DefaultValue(null),
    177          Description("获取或设置XML模式文件路径"),
    178          DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
    179    ]
    180     public virtual string XMLSchemaFile
    181     {
    182         get
    183         {
    184             string s = (string)ViewState["XMLSchemaFile"];
    185             return (s == null? String.Empty : s;
    186         }
    187         set
    188         {
    189             ViewState["XMLSchemaFile"= value;
    190         }
    191     }
    192 
    193     #endregion
    194 
    195     protected override void CreateChildControls()
    196     {
    197         Controls.Clear();
    198         CreateControlHierarchy();
    199         base.CreateChildControls();
    200     }
    201 
    202     protected virtual void CreateControlHierarchy()
    203     {
    204         Table tbParent = new Table();
    205         tbParent.Attributes.Add("Cellpadding""0");
    206         tbParent.Attributes.Add("Cellspacing""0");  
    207 
    208         IEnumerable dataSource = null;
    209         int rowCount = 0;
    210         int columnCount = 0;        
    211         dataSource = GetDataSource();       
    212 
    213         if (dataSource != null)
    214         {            
    215             PropertyDescriptor[] properties = null;
    216             foreach (object dataItem in dataSource)
    217             {               
    218                 properties = GetColumnPropertyDescriptors(dataItem);
    219                 columnCount = properties.Length;                                                    
    220 
    221                 for (int i = 0; i < (columnCount - 3); i++)
    222                 {
    223                     if (blnMultiTypeDataSource == false)
    224                     {
    225                         PropertyDescriptor pdImage = properties[i];
    226                         object cellImage = pdImage.GetValue(dataItem);
    227                         string imageSrc = (string)pdImage.Converter.ConvertTo(cellImage, typeof(string));
    228 
    229                         PropertyDescriptor pdText = properties[i + 2];
    230                         object cellText = pdText.GetValue(dataItem);
    231                         string text = (string)pdText.Converter.ConvertTo(cellText, typeof(string));
    232 
    233                         PropertyDescriptor pdLinkTo = properties[i + 3];
    234                         object cellLinkTo = pdLinkTo.GetValue(dataItem);
    235                         string linkTo = (string)pdLinkTo.Converter.ConvertTo(cellLinkTo, typeof(string));
    236 
    237                         PropertyDescriptor pdLinkTarget = properties[i + 1];                        
    238                         object cellLinkTarget = pdLinkTarget.GetValue(dataItem);                        
    239                         string linkTarget = (string)pdLinkTarget.Converter.ConvertTo(cellLinkTarget, typeof(string));
    240 
    241                         ItemRow item = new ItemRow(imageSrc, text, linkTo, linkTarget);
    242 
    243                         tbParent.Controls.Add(item);
    244                     }
    245                     else
    246                     {
    247                         string imageSrc = "";
    248                         string text = "";
    249                         string linkTo = "";
    250                         string linkTarget = "";
    251                         for (int j = 0; j < columnCount; j++)
    252                         {
    253                             PropertyDescriptor pd = properties[j];
    254                             object objValue = pd.GetValue(dataItem);
    255                             string strValue = (string)pd.Converter.ConvertTo(objValue, typeof(string));
    256                             if (String.Compare(pd.Name, this.DataImageField, true)==0)
    257                             {
    258                                 imageSrc = strValue;
    259                             }
    260                             if (String.Compare(pd.Name, this.DataTextField, true)==0)
    261                             {
    262                                 text = strValue;
    263                             }
    264                             if (String.Compare(pd.Name, this.DataLinkToField, true)==0)
    265                             {
    266                                 linkTo = strValue;
    267                             }
    268                             if (String.Compare(pd.Name, this.DataLinkTargetField, true)==0)
    269                             {
    270                                 linkTarget = strValue;
    271                             }                            
    272                         }
    273                         ItemRow item = new ItemRow(imageSrc, text, linkTo, linkTarget);
    274                         tbParent.Controls.Add(item);
    275                     }
    276                 }
    277                
    278                 this.Controls.Add(tbParent); 
    279                 rowCount++;
    280             }
    281         }
    282        
    283         if (this.XMLDataFile+String.Empty != String.Empty)
    284         {
    285             XmlReaderSettings settings = new XmlReaderSettings();
    286             settings.IgnoreWhitespace = true;
    287             settings.IgnoreComments = true;
    288             NameTable nt = new NameTable();
    289             string link = nt.Add("link");
    290             settings.NameTable = nt;
    291             
    292             //验证
    293             settings.Schemas.Add(null, XmlReader.Create(this.XMLSchemaFile));
    294             settings.ValidationType = ValidationType.Schema;
    295             settings.ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings;
    296             settings.ValidationEventHandler += new ValidationEventHandler(settings_ValidationEventHandler);
    297             
    298             //序列化工厂类
    299             XmlSerializerFactory factory = new XmlSerializerFactory();
    300             
    301             using (XmlReader reader = XmlReader.Create( this.XMLDataFile, settings))
    302             {
    303                 while (reader.Read())
    304                 {
    305                     if (reader.NodeType == XmlNodeType.Element && String.Compare(link, reader.LocalName,true)==0)
    306                     {                        
    307                         XmlSerializer xs = factory.CreateSerializer(typeof(Link));
    308                         Link l = (Link)xs.Deserialize(reader.ReadSubtree());
    309                         ItemRow item = new ItemRow(l.ImageName, l.Text, l.LinkTo, l.LinkTarget);
    310                         tbParent.Rows.Add(item);
    311                     }
    312                 }
    313             }
    314             this.Controls.Add(tbParent); 
    315         }        
    316     }
    317 
    318     /// <summary>
    319     /// 当设置数据源时, 要验证XML文件格式是否正确;  当格式不正确时,此方法用来处理当XML文件格式不正确时,要进行的操作
    320     /// </summary>
    321     /// <param name="sender"></param>
    322     /// <param name="e"></param>
    323     private void settings_ValidationEventHandler(object sender, System.Xml.Schema.ValidationEventArgs e)
    324     {
    325         throw new Exception("数据文件: " + this.XMLDataFile + " 格式不正确! [" + e.Message + "]");
    326     }
    327 
    328     protected override void Render(HtmlTextWriter writer)
    329     {       
    330         base.Render(writer);        
    331     }
    332    
    333     public override void DataBind()
    334     {       
    335         base.OnDataBinding(EventArgs.Empty);
    336         Controls.Clear();
    337         ClearChildViewState();
    338         TrackViewState();        
    339         CreateControlHierarchy();
    340         ChildControlsCreated = true;
    341     }
    342 
    343     private PropertyDescriptor[] GetColumnPropertyDescriptors(object dataItem)
    344     {
    345         ArrayList props = new ArrayList();
    346         PropertyDescriptorCollection propDescs = TypeDescriptor.GetProperties(dataItem);
    347         foreach (PropertyDescriptor pd in propDescs)
    348         {
    349             Type propType = pd.PropertyType;
    350             TypeConverter converter = TypeDescriptor.GetConverter(propType);
    351             if ((converter != null&& converter.CanConvertTo(typeof(string)))
    352             {
    353                 props.Add(pd);
    354             }
    355         }        
    356         PropertyDescriptor[] columns = new PropertyDescriptor[props.Count];
    357         props.CopyTo(columns, 0);
    358         return columns;
    359     }
    360 
    361 
    362     //获取数据源,将数据源中的数据都转换为IEnumerable类型
    363     protected virtual IEnumerable GetDataSource()
    364     {
    365         if (_dataSource == null)
    366         {
    367             return null;
    368         }
    369         IEnumerable resolvedDataSource = _dataSource as IEnumerable;
    370         if (resolvedDataSource != null)
    371         {
    372             return resolvedDataSource; //强类型集合类型/ArrayList
    373         }
    374 
    375         this.blnMultiTypeDataSource = true;
    376 
    377         IListSource listSource = _dataSource as IListSource;
    378         if (listSource != null)
    379         {
    380             IList memberList = listSource.GetList();
    381 
    382             if (listSource.ContainsListCollection == false)
    383             {
    384                 return (IEnumerable)memberList; //DataTable
    385             }
    386             ITypedList typedMemberList = memberList as ITypedList;
    387             if (typedMemberList != null)
    388             {
    389                 PropertyDescriptorCollection propDescs = typedMemberList.GetItemProperties(new PropertyDescriptor[0]);
    390                 PropertyDescriptor memberProperty = null;
    391 
    392                 if ((propDescs != null&& (propDescs.Count != 0))
    393                 {
    394                     string dataMember = DataMember;
    395 
    396                     if (dataMember.Length == 0)
    397                     {
    398                         memberProperty = propDescs[0];
    399                     }
    400                     else
    401                     {
    402                         memberProperty = propDescs.Find(dataMember, true);
    403                     }
    404 
    405                     if (memberProperty != null)
    406                     {
    407                         object listRow = memberList[0];
    408                         object list = memberProperty.GetValue(listRow);
    409 
    410                         if (list is IEnumerable)
    411                         {
    412                             return (IEnumerable)list; //DataSet
    413                         }
    414                     }
    415                     throw new Exception("未能找到有效的DataMember.");
    416                 }
    417 
    418                 throw new Exception("数据源中不包含任何数据对象.");
    419             }
    420         }
    421         return null;
    422     }        
    423 }

    2. 使用不同数据源绑定

     1 /// <summary>
     2 /// Author: [ ChengKing(ZhengJian) ] 
     3 /// Blog:   Http://blog.csdn.net/ChengKing
     4 /// </summary>
     5 public partial class _Default : System.Web.UI.Page 
     6 {   
     7     protected void Page_Load(object sender, EventArgs e)
     8     {
     9         /// <summary>
    10         /// 测试通过各种数据源进行绑定
    11         /// </summary>
    12 
    13         //(一). 绑定强类型集合类型
    14         ItemList itemList = new ItemList();
    15         itemList.Add(new Item(@"Images\img.gif""宁波宇泰软件股份有限公司""http://www.xframe.com.cn""blank"));
    16         itemList.Add(new Item(@"Images\img.gif""宁波宇泰软件开发有限公司""http://www.xframe.com.cn""blank"));
    17         DataSourceInUserControl1.DataSource = itemList;
    18         DataSourceInUserControl1.DataBind();
    19 
    20         //(二). 绑定ArraList集合类型
    21         ArrayList al = new ArrayList();
    22         al.Add(new Item(@"Images\img.gif""宁波宇泰软件股份有限公司""http://www.xframe.com.cn""blank"));
    23         al.Add(new Item(@"Images\img.gif""宁波宇泰软件开发有限公司""http://www.xframe.com.cn""blank"));
    24         DataSourceInUserControl1.DataSource = al;
    25         DataSourceInUserControl1.DataBind();
    26 
    27         //(三). 测试绑定DataTable
    28         DataTable dt = new CusDataSource().CreateDataTable();
    29         DataSourceInUserControl1.DataSource = dt;
    30         DataSourceInUserControl1.DataImageField = "ImageName";
    31         DataSourceInUserControl1.DataTextField = "Text";
    32         DataSourceInUserControl1.DataLinkToField = "LinkTo";
    33         DataSourceInUserControl1.DataLinkTargetField = "LinkTarget";
    34         DataSourceInUserControl1.DataBind();
    35 
    36         //(四). 测试绑定DataSet
    37         DataSet ds = new CusDataSource().CreateDataSet();
    38         DataSourceInUserControl1.DataSource = ds;
    39         DataSourceInUserControl1.DataMember = ds.Tables[0].TableName; //如果不声明此句,会默认取DataSet中的第一个表
    40         DataSourceInUserControl1.DataImageField = "ImageName";
    41         DataSourceInUserControl1.DataTextField = "Text";
    42         DataSourceInUserControl1.DataLinkToField = "LinkTo";
    43         DataSourceInUserControl1.DataLinkTargetField = "LinkTarget";
    44         DataSourceInUserControl1.DataBind(); 
    45 
    46         ////(五). 测试绑定XML
    47         string strDataFile = Path.Combine(Request.PhysicalApplicationPath, "LinkList.xml");
    48         string strSchemaFile = Path.Combine(Request.PhysicalApplicationPath, "LinkList.xsd");
    49         DataSourceInUserControl1.XMLDataFile = strDataFile;
    50         DataSourceInUserControl1.XMLSchemaFile = strSchemaFile;
    51     }
    52 }
        
     
       
    (四). 示例代码下载
        
  • 相关阅读:
    终于有人讲清楚准确率(accuracy)、召唤率(recall)和精确率(precision)的关系了
    leetcode之两数相加解题思路
    Django-rest-framwork——认证
    py2neo详细介绍第一章
    springdata的懒加载时机
    错题记录
    SSM框架的优势?
    2020-06-30 pol实现execl导入导出
    2020-06-30 动态sql
    String 、StringBuilder 、StringBuffer 的区别? 什么情况下用“+”运算符进行字符串连接比调用 StringBuffer/StringBuilder对象的 append 方法连接字符串性能更好?.
  • 原文地址:https://www.cnblogs.com/scgw/p/847161.html
Copyright © 2011-2022 走看看