您的位置:首页 > 编程语言 > ASP

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

2008-04-05 18:55 1146 查看
(一). 概要

开发<数据绑定用户控件>, 要实现一个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 }

[align=center][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left](四). 示例代码下载[/align]
[align=left][/align]
[align=left] http://files.cnblogs.com/MVP33650/DataSource%20of%20UserControl.rar[/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left](五). 更多自定义控件开发相关文章[/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left] http://blog.csdn.net/ChengKing/category/288694.aspx[/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=center][/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐