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. 用户控件部分
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. 使用不同数据源绑定
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 }
转载于:https://www.cnblogs.com/scgw/archive/2007/08/08/847161.html
Asp.net 2.0 自定义控件开发专题讲解[为用户控件增加DataSource属性, 能够自动识别不同数据源](示例代码下载)...相关推荐
- Asp.net 2.0 动态加载其他子目录用户控件问题
通常我们要在程序中动态加载用户控件: 方法很简单直接在程序里键入: (usercontrol type)a = (usercontrol type)Page.LoadControl("~/x ...
- ASP.NET开发:在用户控件中添加属性
在WEB开发中,可重用的代码我们可以把它写成一个通用模块供需要的地方来引用.本文就是介绍在ASP.NET的web编程时,如何在用户控件中添加属性,实现这种方法:举例说明详解. 在WEB开发中经常有一些 ...
- [导入]Asp.net 2.0 自定义控件开发[创建自定义浮动菜单FloadMenu控件][示例代码下载]...
Asp.net 2.0 自定义控件开发[创建自定义浮动菜单FloadMenu控件][示例代码下载] 文章来源:http://blog.csdn.net/chengking/archive/2007/0 ...
- [导入]Asp.net 2.0 自定义控件开发[实现自动计算功能(AutoComputeControl)][示例代码下载]...
Asp.net 2.0 自定义控件开发[实现自动计算功能(AutoComputeControl)][重点推荐控件][示例代码下载] 文章来源:http://blog.csdn.net/chengkin ...
- 开发和使用Web用户控件
在 ASP.NET 的开发中 Web 用户控件的开发和使用是一项必不可少的技术,在对这项技术的一番研究后写下了这篇随笔,不过确实担心这么初级的东东放到原创首页上会被拍砖头. 1.简介 2.创建 Web ...
- [MOSS开发]:如何使用用户控件
如果是纯手工开发web part,其实还是比较困难的,因为这种类型的web part是以类库的形式出现,没有可视化的界面,完全由代码写出来,包含控件的样式,属性,事件等等.开发过自定义控件的朋友可能会 ...
- ASP.NET重用代码技术 - 用户控件技术
作者: 苏红超 使用ASP.NET中的代码绑定技术来使得代码重用变得简单可行.我们发现,利用代码绑定技术我们可以容易的将我们的代码和内容分离开来,利用它可以建立可重用的代码,只是这种技术本身也存在着一 ...
- 用户控件和自定义控件
关 键 词 Server Control 服务器控件 User Control 用户控件,ASP.NET服务器控件的一种(一般后缀名为.ASCX文件) Custom Control 自定义控件,ASP ...
- ASP.NET的用户控件
本文介绍如何在ASP.NET中创建用户控件,控件属性的动态修改以及控件的事件出发机制. 简介 ASP.NET的服务端控件使得Web开发工作变得更为简单,功能更为强大.我们介绍过如何在ASP.NET页面 ...
最新文章
- 产品经理必备知识之网页设计系列(二)-如何设计出一个优秀的界面
- 从最新的编程语言排行看,Java真的要凉了吗?
- 如何实现一套可切换的声网+阿里的直播引擎
- 使用iperf进行设备吞吐量测试
- 牛客挑战赛47 C 条件(Floyd bitset优化)
- 从0到1写RT-Thread内核——空闲线程与阻塞延时的实现
- 数据结构实验之查找四:二分查找
- windows安装TortoiseGit
- pySpark加载数据
- C++_类和对象_对象特性_成员变量占用对象内存_成员函数_静态成员函数_静态变量_都不占用对象内存_他们是分开存储的---C++语言工作笔记048
- python zlib module_python 安装 setuptools Compression requires the (missing) zlib module 的解决方案...
- npm install 错误 安装 chromedriver 失败的解决办法
- python爬虫设计思路_python网络爬虫(9)构建基础爬虫思路
- django从入门到放弃之001.初探
- Proteus8.10软件安装教程
- 计算机科学概论:计算机科学中的百科全书
- 软件开发过程模型——喷泉模型
- 大地坐标系转换火星坐标系
- 已解决IndentationError: unindent does not match any oute r indentation Level
- python中response是什么意思_对python中各个response的使用说明
热门文章
- vue 子页面调用父页面常用方式
- js math保留两位小数
- linux查看宽带ip是否动态,linux CentOS系统查看实时宽带的办法
- excel判断两列中同一行的数据是否一致
- java 注释添加引用_java – 如何引用注释处理中的方法的实现?
- enlink请输入正确服务器地址,Enlink
- python 千位分隔符_玩转千位分隔符输出 - leejun2005的个人页面 - OSCHINA - 中文开源技术交流社区...
- python课程结课感悟_科学网—《互联网+引论与Python》课堂感想(七) - 张忆文的博文...
- 2018年4月工业用微型计算机,2018年自考工业用微型计算机押密试题及答案(六)...
- 系统集成的系统架构图的相关的vsd素材_信息系统集成专业技术知识:软件架构...