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  }
    
 
   
(四). 示例代码下载
    
        
(五). 更多自定义控件开发相关文章
     
 
 

 

 

      

 

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值