(一).  概要

开发<数据绑定用户控件>, 要实现一个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 }
    
 
   
(四). 示例代码下载
    
         http://files.cnblogs.com/MVP33650/DataSource%20of%20UserControl.rar

转载于:https://www.cnblogs.com/scgw/archive/2007/08/08/847161.html

Asp.net 2.0 自定义控件开发专题讲解[为用户控件增加DataSource属性, 能够自动识别不同数据源](示例代码下载)...相关推荐

  1. Asp.net 2.0 动态加载其他子目录用户控件问题

    通常我们要在程序中动态加载用户控件: 方法很简单直接在程序里键入: (usercontrol type)a = (usercontrol type)Page.LoadControl("~/x ...

  2. ASP.NET开发:在用户控件中添加属性

    在WEB开发中,可重用的代码我们可以把它写成一个通用模块供需要的地方来引用.本文就是介绍在ASP.NET的web编程时,如何在用户控件中添加属性,实现这种方法:举例说明详解. 在WEB开发中经常有一些 ...

  3. [导入]Asp.net 2.0 自定义控件开发[创建自定义浮动菜单FloadMenu控件][示例代码下载]...

    Asp.net 2.0 自定义控件开发[创建自定义浮动菜单FloadMenu控件][示例代码下载] 文章来源:http://blog.csdn.net/chengking/archive/2007/0 ...

  4. [导入]Asp.net 2.0 自定义控件开发[实现自动计算功能(AutoComputeControl)][示例代码下载]...

    Asp.net 2.0 自定义控件开发[实现自动计算功能(AutoComputeControl)][重点推荐控件][示例代码下载] 文章来源:http://blog.csdn.net/chengkin ...

  5. 开发和使用Web用户控件

    在 ASP.NET 的开发中 Web 用户控件的开发和使用是一项必不可少的技术,在对这项技术的一番研究后写下了这篇随笔,不过确实担心这么初级的东东放到原创首页上会被拍砖头. 1.简介 2.创建 Web ...

  6. [MOSS开发]:如何使用用户控件

    如果是纯手工开发web part,其实还是比较困难的,因为这种类型的web part是以类库的形式出现,没有可视化的界面,完全由代码写出来,包含控件的样式,属性,事件等等.开发过自定义控件的朋友可能会 ...

  7. ASP.NET重用代码技术 - 用户控件技术

    作者: 苏红超 使用ASP.NET中的代码绑定技术来使得代码重用变得简单可行.我们发现,利用代码绑定技术我们可以容易的将我们的代码和内容分离开来,利用它可以建立可重用的代码,只是这种技术本身也存在着一 ...

  8. 用户控件和自定义控件

    关 键 词 Server Control 服务器控件 User Control 用户控件,ASP.NET服务器控件的一种(一般后缀名为.ASCX文件) Custom Control 自定义控件,ASP ...

  9. ASP.NET的用户控件

    本文介绍如何在ASP.NET中创建用户控件,控件属性的动态修改以及控件的事件出发机制. 简介 ASP.NET的服务端控件使得Web开发工作变得更为简单,功能更为强大.我们介绍过如何在ASP.NET页面 ...

最新文章

  1. 产品经理必备知识之网页设计系列(二)-如何设计出一个优秀的界面
  2. 从最新的编程语言排行看,Java真的要凉了吗?
  3. 如何实现一套可切换的声网+阿里的直播引擎
  4. 使用iperf进行设备吞吐量测试
  5. 牛客挑战赛47 C 条件(Floyd bitset优化)
  6. 从0到1写RT-Thread内核——空闲线程与阻塞延时的实现
  7. 数据结构实验之查找四:二分查找
  8. windows安装TortoiseGit
  9. pySpark加载数据
  10. C++_类和对象_对象特性_成员变量占用对象内存_成员函数_静态成员函数_静态变量_都不占用对象内存_他们是分开存储的---C++语言工作笔记048
  11. python zlib module_python 安装 setuptools Compression requires the (missing) zlib module 的解决方案...
  12. npm install 错误 安装 chromedriver 失败的解决办法
  13. python爬虫设计思路_python网络爬虫(9)构建基础爬虫思路
  14. django从入门到放弃之001.初探
  15. Proteus8.10软件安装教程
  16. 计算机科学概论:计算机科学中的百科全书
  17. 软件开发过程模型——喷泉模型
  18. 大地坐标系转换火星坐标系
  19. 已解决IndentationError: unindent does not match any oute r indentation Level
  20. python中response是什么意思_对python中各个response的使用说明

热门文章

  1. vue 子页面调用父页面常用方式
  2. js math保留两位小数
  3. linux查看宽带ip是否动态,linux CentOS系统查看实时宽带的办法
  4. excel判断两列中同一行的数据是否一致
  5. java 注释添加引用_java – 如何引用注释处理中的方法的实现?
  6. enlink请输入正确服务器地址,Enlink
  7. python 千位分隔符_玩转千位分隔符输出 - leejun2005的个人页面 - OSCHINA - 中文开源技术交流社区...
  8. python课程结课感悟_科学网—《互联网+引论与Python》课堂感想(七) - 张忆文的博文...
  9. 2018年4月工业用微型计算机,2018年自考工业用微型计算机押密试题及答案(六)...
  10. 系统集成的系统架构图的相关的vsd素材_信息系统集成专业技术知识:软件架构...