惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Simon Willison's Weblog
Simon Willison's Weblog
G
Google Developers Blog
Spread Privacy
Spread Privacy
I
InfoQ
V
V2EX
S
Schneier on Security
小众软件
小众软件
C
CERT Recently Published Vulnerability Notes
博客园 - 聂微东
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Stack Overflow Blog
Stack Overflow Blog
T
Threat Research - Cisco Blogs
L
Lohrmann on Cybersecurity
Recent Announcements
Recent Announcements
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Attack and Defense Labs
Attack and Defense Labs
云风的 BLOG
云风的 BLOG
The Hacker News
The Hacker News
S
SegmentFault 最新的问题
C
Cybersecurity and Infrastructure Security Agency CISA
NISL@THU
NISL@THU
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
GbyAI
GbyAI
Latest news
Latest news
S
Secure Thoughts
Project Zero
Project Zero
MongoDB | Blog
MongoDB | Blog
I
Intezer
Security Latest
Security Latest
Apple Machine Learning Research
Apple Machine Learning Research
Vercel News
Vercel News
N
Netflix TechBlog - Medium
V2EX - 技术
V2EX - 技术
量子位
T
Threatpost
T
The Blog of Author Tim Ferriss
Y
Y Combinator Blog
T
Tor Project blog
A
Arctic Wolf
Microsoft Security Blog
Microsoft Security Blog
T
The Exploit Database - CXSecurity.com
大猫的无限游戏
大猫的无限游戏
T
Tailwind CSS Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
C
Check Point Blog
博客园 - Franky
Google DeepMind News
Google DeepMind News
The Register - Security
The Register - Security
The GitHub Blog
The GitHub Blog
L
LINUX DO - 热门话题

博客园 - 吕艳阳

asp.net 重新启动应用程序 eWebEditor在线文本编辑器最新版(V4.6) 用DataReader 分页与几种传统的分页方法的比较 CodeSmith实体类模板 Oracle中取余的方法 (转)C#新特性:可空类型 (转)asp.net控件设计时支持(3) javascript事件列表解说 返回数据库内所有表的字段 网线水晶头的接法 Access密码破解工具 简单介绍一下asp.net中DataGrid的使用(视频教程) Asp.net中文件的上传和下载(视频教程) 如何在asp中,使用vb来开发dll组件 (提供视频下载) 操作系统常用技巧 Oracle9i 用户登录存储过程 Oracle 冷备份操作 Oralce9i 获取单个字段的值 Oracle 9i 返回一个记录集的方法
(转)asp.net自定义控件(数据绑定)
吕艳阳 · 2008-09-24 · via 博客园 - 吕艳阳

数据绑定的概念是:通过提供一个DataSource属性来指定数据源,当控件呈现自己时,从数据源中抽取数据,并将这些数据作为控件的一部分进行呈现。使用的数据源一般是直接或间接实现了IEnumerable接口的数据,如ArrayList、IDataReader、DataTable等,这样可以方便的进行数据的查找。可以想象的到,在进行数据绑定时用的是遍历的办法。一般来说,控件还需要维护自己的状态,这就需要对ViewState进行操作。
下面用一个简单的支持数据绑定的控件来具体说明。该控件是按照《Essential ASP.NET with Examples in C#》中的自定义控件部分的讲解完成的,但是做了自己认为对的改动。我自己加上了详细的注释。
这是一个简单的控件,只能够显示数据表的某一列数据。
最重要的就是重写的OnDataBinding方法,这个是DataBinding事件的处理方法,当用户调用了DataBind后引发。在这里将指定的数据源转换成IEnumerable,然后就可以获得IEnumerator形式的数据,最后用遍历的办法来得到数据。
状态的维持通过重写LoadViewState和SaveViewState方法来完成。cacheList是我们用来保存数据的ArrayList,通过把它保存到ViewState,可以避免多次存取数据。
getResolvedDataSource和getDataItem是两个很有用的辅助方法,前者帮助将数据源转换成IEnumerable,后者可以取出具体的数据。这两个方法都要先判断数据类型,然后根据具体的情况进行下一步。
using System;
using System.Data;
using System.Web.UI;
using System.Collections;
using System.ComponentModel;

namespace CC
{
/// <summary>
/// 可以进行数据绑定的控件,简单模型,所以只能显示指定的一列记录
/// </summary>
public class DataBindControl : Control
{
//要显示的字段
private string dataTextField;

[Category("自定义属性"),DefaultValue(""),Description("要显示的数据源的字段")]
public string DataTextField
{
set { this.dataTextField=value; }
get { return this.dataTextField; }
}

//数据源
private object dataSource;

[Category("自定义属性"),Description("数据源")]
public object DataSource
{
set{ this.dataSource=value; }
get{ return this.dataSource; }
}

/// <summary>
/// 处理数据源,转换成IEnumerable,方便进行下一步操作
/// </summary>
/// <param name="source">数据源,先统一装箱</param>
/// <returns>数据源的IEnumerable形式</returns>
private IEnumerable getResolvedDataSource(object source)
{
if(source is IEnumerable)
return (IEnumerable)source;
else if(source is IList)
return (IEnumerable)source;
else if(source is DataSet)
return (IEnumerable)(((DataSet)source).Tables[0].DefaultView);
else if (source is DataTable)
return (IEnumerable)(((DataTable)source).DefaultView);
else
return null;
}

/// <summary>
/// 从已转化为IEnumerable的数据源的一行中取出需要的DataTextField规定的数据
/// </summary>
/// <param name="item">已转化为IEnumerable的数据源的一行数据</param>
/// <returns>取得的数据的string形式</returns>
private string getDataItem(object item)
{
if(item is IDataRecord)
return ((IDataRecord)item)[this.dataTextField].ToString();
else if(item is DataRowView)
return ((DataRowView)item)[this.dataTextField].ToString();
else
return item.ToString();
}

//用来存放数据的ArrayList,这个也配合ViewState使用
private ArrayList cacheList=new ArrayList();

/// <summary>
/// 处理DataBinding事件,把数据源中需要的数据加到一个ArrayList中。
/// </summary>
/// <param name="e">EventArgs</param>
protected override void OnDataBinding(EventArgs e)
{
base.OnDataBinding (e);
if(this.dataSource!=null)
{
//如果Count为0,则表示是第一次加载
if(this.cacheList.Count==0)
{
IEnumerable source=this.getResolvedDataSource(this.dataSource);
IEnumerator item=source.GetEnumerator();
while(item.MoveNext())
{
//保存数据
this.cacheList.Add(this.getDataItem(item.Current));
}
}
}
}

/// <summary>
/// 呈现,用遍历来循环输出ArrayList中的数据
/// </summary>
/// <param name="writer">HtmlTextWriter</param>
protected override void Render(HtmlTextWriter writer)
{
foreach(string s in this.cacheList)
{
writer.RenderBeginTag(HtmlTextWriterTag.Div);
writer.Write(s);
writer.RenderEndTag();
}
}

/// <summary>
/// 保存自页回发到服务器后发生的任何服务器控件视图状态更改。
/// </summary>
/// <returns>返回服务器控件的当前视图状态。</returns>
protected override object SaveViewState()
{
object[] vState=new object[]{base.SaveViewState(),this.cacheList};
return vState;
}

/// <summary>
///从 SaveViewState 方法保存的上一个页请求还原视图状态信息。
/// </summary>
/// <param name="savedState">表示要还原的控件状态的 Object</param>
protected override void LoadViewState(object savedState)
{
if(savedState!=null)
{
object[] vState=(object[])savedState;
if(vState[0]!=null)
base.LoadViewState(vState[0]);
if(vState[1]!=null)
this.cacheList=(ArrayList)vState[1];
}
}

}
}
本文转自http://hi.baidu.com/dongyuejiang/blog/item/336fdb07cf08d9cb7a894759.html