博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Asp.net 2.0 自定义控件开发专题讲解[为用户控件增加DataSource属性, 能够自动识别不同数据源](示例代码下载)
阅读量:4190 次
发布时间:2019-05-26

本文共 13377 字,大约阅读时间需要 44 分钟。

(一).  概要

          开发 <数据绑定用户控件> , 要实现一个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 
///
 
  7 /// Author: [ ChengKing(ZhengJian) ] 
  8 /// Blog:   Http://blog.csdn.net/ChengKing
  9 /// 
 10 
public
 partial 
class
 LinkList : System.Web.UI.UserControl
 11 
{
 12 
 13 
    
private
 
bool
 blnMultiTypeDataSource 
=
 
false
;
 14 
 15 
    
#region
 属性   
 16 
 17 
 18 
 19 
    
///
 
 20     /// 表格每行图像控件的指向图片名称
 21     /// 
 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 
    
///
 
 42     /// 表格每行链接控件显示的文本
 43     /// 
    
 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 
    
///
 
 64     /// 表格第行链接控件的跳转目标页面链接
 65     /// 
 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 
    
///
 
 86     /// 表格每行的链接目标页面打开方式
 87     /// 
 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 
    
///
 
319     /// 当设置数据源时, 要验证XML文件格式是否正确;  当格式不正确时,此方法用来处理当XML文件格式不正确时,要进行的操作
320     /// 
321 
    
///
 
322 
    
///
 
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 
///
 
 2 /// Author: [ ChengKing(ZhengJian) ] 
 3 /// Blog:   Http://blog.csdn.net/ChengKing
 4 /// 
 5 
public
 partial 
class
 _Default : System.Web.UI.Page 
 6 
{   
 7 
    
protected
 
void
 Page_Load(
object
 sender, EventArgs e)
 8 
    {
 9 
        
///
 
10         /// 测试通过各种数据源进行绑定
11         /// 
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 
}
    
 
   
(四). 示例代码下载
    
        
        
(五). 更多自定义控件开发相关文章
     
        
 
 

 

 

      

 

 

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1610497

你可能感兴趣的文章
删列造序
查看>>
使括号有效的最少添加
查看>>
令牌放置
查看>>
回溯法思想
查看>>
子集和问题
查看>>
旅行售货员问题
查看>>
区域和检索 - 数组不可变
查看>>
整数分解
查看>>
最长有效括号
查看>>
救生艇
查看>>
Android中自定义圆形图片(一)
查看>>
Android中ViewPager自动加手动轮播
查看>>
Android中Fragment点击切换与添加ViewPager滑动切换
查看>>
Java多线程-阻塞队列BlockingQueue
查看>>
Windows:Apache与Tomcat集群调优
查看>>
Apache+2Tomcat 集群及调优
查看>>
通向架构师的道路(第三天)之apache性能调优
查看>>
Tomcat性能调优
查看>>
Tomcat集群
查看>>
quartz在集群环境下的最终解决方案
查看>>