一, 给控件提供支持绑定数据源的功能
要实现很简单,只有从新类 CompositeDataBoundControl 派生,并实现CreateChildControls方法就可以了。
先做一个简单的例子理解一下这个类的使用:
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace XLSoft.WebControls
{
public class MyDataGrid1 : CompositeDataBoundControl
{
public string DataName
{
get
{
object o = ViewState["DataName"];
if (o == null)
return "";
return (string)o;
}
set { ViewState["DataName"] = value; }
}
protected override int CreateChildControls(IEnumerable dataSource, bool dataBinding)
{
int itemCount = 0;
if (dataBinding)
{
foreach (object obj in dataSource)
{
Label lbl = new Label();
lbl.Text = DataBinder.GetPropertyValue(obj, DataName).ToString() + " | ";
Controls.Add(lbl);
itemCount++;
}
}
return itemCount;
}
}
}
{
DataTable dt = new DataTable();
dt.Columns.Add("text");
DataRow dr1 = dt.NewRow();
dr1[0] = "111";
DataRow dr2 = dt.NewRow();
dr2[0] = "222";
dt.Rows.Add(dr1);
dt.Rows.Add(dr2);
this.MyDataGrid11.DataSource = dt;
this.MyDataGrid11.DataBind()
}
二, 添加多列的属性
上面的实验只是做了实现数据源控件的功能,如果是要做表格控件,其中的label就可以换成TableRow ,并添加到Table,这样同样可以做出表格,不过只有一列(DataName),当然可以把多个列名合并放在DataName中,考虑到列可能会有其他属性,比如HeaderText,这样做并不合理。于是换成 Colunms集合对象。
{
public MyColunm() { }
public MyColunm(string name, string headertext, string format)
{
this._name = name;
this._headerText = headertext;
this._format = format;
}
private string _name;
private string _headerText;
private string _format;
public string Format
{
get { return _format; }
set{ _format = value; }
}
public string HeaderText
{
get { return _headerText; }
set { _headerText = value; }
}
public string Name
{
get { return _name; }
set { _name = value; }
}
}
public class MyColunmCollection : List<MyColunm>{}
public class MyDataGrid2 : CompositeDataBoundControl
{
private MyColunmCollection _colunms = new MyColunmCollection();
public MyColunmCollection Colunms
{
get { return _colunms; }
}
protected override int CreateChildControls(IEnumerable dataSource, bool dataBinding)
{
Table table = new Table();
if (dataBinding)
{
TableHeaderRow trHeader = new TableHeaderRow();
foreach (MyColunm col in Colunms)
{
TableHeaderCell cell = new TableHeaderCell();
cell.Text = col.HeaderText;
trHeader.Cells.Add(cell);
}
table.Rows.Add(trHeader); //Add Header Row
foreach (object obj in dataSource)
{
TableRow tr = new TableRow();
foreach (MyColunm col in Colunms)
{
TableCell cell = new TableCell();
if (string.IsNullOrEmpty(col.Format))
cell.Text = DataBinder.GetPropertyValue(obj, col.Name).ToString();
else
cell.Text = DataBinder.GetPropertyValue(obj, col.Name, col.Format);
tr.Cells.Add(cell);
}
table.Rows.Add(tr);
}
}
Controls.Add(table);
return 1;
}
}
三、添加子标签
简单来说,添加特性:ParseChildren(true,"Colunms"),就可以把子标签作为属性填充到Colunms中,
关于ParseChildren,MSDN有这样的解释:
1:在开发ASP.NET 服务器控件时,ParseChildrenAttribute 类指示页分析器应如何处理页上声明的服务器控件标记中嵌套的内容.
2:ParseChildrenAttribute 类允许您以 ParseChildrenAttribute 元数据属性标记服务器控件来为自定义服务器控件指定分析逻辑。
3:以元数据属性 (Attribute) ParseChildren(true) 标记服务器控件将指示分析器把包含在服务器控件标记内的元素解释为属性 (Property)。
4:以元数据属性 (Attribute) ParseChildren(true,"<Default Property>") 标记服务器控件将把 DefaultProperty 属性 (Property) 设置为传递到该属性 (Attribute) 的属性 (Property) 名称。
5:以元数据属性 ParseChildren(false)(默认值)标记服务器控件将指示分析器把包含在服务器控件标记中的元素解释为将通过关联的 ControlBuilder 进行分析的内容,即解释为控件。
<MYUI:MyColunm Name="Lastname" HeaderText="名字" runat="server"></MYUI:MyColunm>
<MYUI:MyColunm Name="BirthDate" HeaderText="生日" Format="{0:yyyy-mm}" runat="server"></MYUI:MyColunm>
</MYUI:MyDataGrid2>
{
public employee(string lastname, DateTime birthdate)
{
this._lastname = lastname;
this._birthDate = birthdate;
}
private string _lastname;
private DateTime _birthDate;
public string Lastname
{
get { return _lastname; }
set { _lastname = value; }
}
public DateTime BirthDate
{
get { return _birthDate; }
set { _birthDate = value; }
}
}
public partial class MyDataGrid2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
employee[] employees = { new employee("xie", DateTime.Now), new employee("chen", DateTime.Now) };
this.MyDataGrid1.DataSource = employees;
this.MyDataGrid1.DataBind();
}
}
三、设置设计时格式
做到这个基本上可以实现了,不过设计时还是没办法正常显示。
{
cell.Text = "数据绑定";
tr.Cells.Add(cell);
continue;
}
/Files/JackyXie/MyDataGrid.rar