近日在做GridView动态加载模板列的问题是,发现微软的GridView功能竟然如此捉襟见肘。本来想一个AddColumn()即可搞定的问题,到现实中却发现,远非想像中的那般美好。。。。。
于是在网上查了相关的示例,发现都只泛泛讲了一下原理,真正可实用的没有发现,所以一狠心,整理了一下这方面的代码,写了一个派生类。在只使用TextBox模板列的情况下还可以满足要求,至少满足我的要求了。各位可以根据需要扩展即可。本人菜鸟一个,不求甚解,只为实现功能,望高人多多指点。
///
<summary>
///
GridView动态模板列
///
</summary>
///
<example>
///
TemplateFieldEx te = new TemplateFieldEx(150, "动态添加列", "idddd", "id", false);
///
GridView1.Columns.Add(te);
///
</example>
public
class
TemplateFieldEx : TemplateField
{
///
<summary>
///
此无参构造必须实现,否则出错
///
</summary>
public
TemplateFieldEx()
:
base
()
{
}
///
<summary>
///
构造模板列,具体样式请在GridView中直接设置
///
</summary>
///
<param name="nWidth">
当前列限定宽度
</param>
///
<param name="strColumnText">
标题字符串
</param>
///
<param name="strTxtID">
插入的编辑框ID,注意勿重复
</param>
///
<param name="strField">
当前弄绑定的字段
</param>
///
<param name="bReadOnly">
编辑框是否只读
</param>
public
TemplateFieldEx(
int
nWidth,
string
strColumnText,
string
strTxtID,
string
strField,
bool
bReadOnly):
base
()
{
this
.ControlStyle.Width
=
Unit.Pixel(nWidth);
this
.ItemStyle.Width
=
Unit.Pixel(nWidth);
this
.ShowHeader
=
true
;
this
.HeaderTemplate
=
new
GridViewItemTemplate(strColumnText);
this
.ItemTemplate
=
new
GridViewItemTemplate(strTxtID, strField, bReadOnly);
}
}
///
<summary>
///
GridView模板项
///
</summary>
public
class
GridViewItemTemplate : ITemplate
{
private
DataControlRowType m_type;
private
bool
m_bReadOnly;
private
string
m_strTxtID;
private
string
m_strColumnText;
private
string
m_strField;
///
<summary>
///
此无参构造必须实现,否则出错
///
</summary>
public
GridViewItemTemplate() :
base
()
{
}
///
<summary>
///
构造表头列对象
///
</summary>
///
<param name="strColumnText">
表头字符串
</param>
public
GridViewItemTemplate(
string
strColumnText)
{
m_type
=
DataControlRowType.Header;
m_strColumnText
=
strColumnText;
}
///
<summary>
///
构造元素行对象
///
</summary>
///
<param name="strTxtID">
当前TextBox控件ID
</param>
///
<param name="strField">
当前TextBox控件绑定的字段
</param>
///
<param name="bReadOnly">
TextBox是否只读
</param>
public
GridViewItemTemplate(
string
strTxtID,
string
strField,
bool
bReadOnly)
{
m_type
=
DataControlRowType.DataRow;
m_strTxtID
=
strTxtID;
m_strField
=
strField;
m_bReadOnly
=
bReadOnly;
}
public
void
InstantiateIn(System.Web.UI.Control container)
{
switch
(m_type)
{
case
DataControlRowType.Header:
Literal l
=
new
Literal();
l.Text
=
m_strColumnText;
container.Controls.Add(l);
break
;
case
DataControlRowType.DataRow:
TextBox tb
=
new
TextBox();
tb.ID = m_strTxtID;
tb.Width
=
Unit.Percentage(
100
);
tb.BorderStyle
=
BorderStyle.None;
tb.DataBinding
+=
new
EventHandler(TextBox_DataBinding);
tb.ReadOnly
=
m_bReadOnly;
container.Controls.Add(tb);
break
;
default
:
break
;
}
}
private
void
TextBox_DataBinding(
object
sender, EventArgs e)
{
TextBox tb
=
sender
as
TextBox;
GridViewRow gvr
=
tb.NamingContainer
as
GridViewRow;
tb.Text
=
DataBinder.Eval(gvr.DataItem, m_strField).ToString();
}
}
示例代码如下:
protected
void
Page_Load(
object
sender, EventArgs e)
{
//
注意此处不可放在if(!IsPostBack)中,否则任何一个PostBack命令将会导致此模板列数据丢失,不知何故??
PerformDataBind();
}
private
void
PerformDataBind()
{
//
注意:此处需要删除列,否则重新添加会导致模板列数量增加
GridView1.Columns.Clear();
TemplateFieldEx te
=
new
TemplateFieldEx(
150
,
"
动态添加列
"
,
"
t1
"
,
"
id
"
,
false
);
GridView1.Columns.Add(te);
te
=
new
TemplateFieldEx(
150
,
"
text
"
,
"
t2
"
,
"
text
"
,
true
);
GridView1.Columns.Add(te);
GridView1.DataSource
=
CreateDataSource();
GridView1.DataBind();
}
///
<summary>
///
构造数据源
///
</summary>
///
<returns></returns>
DataTable CreateDataSource()
{
DataTable dt
=
new
DataTable();
DataRow dr;
dt.Columns.Add(
new
DataColumn(
"
id
"
,
typeof
(Int32)));
dt.Columns.Add(
new
DataColumn(
"
text
"
,
typeof
(
string
)));
for
(
int
i
=
0
; i
<
16
; i
++
)
{
dr
=
dt.NewRow();
dr[
0
]
=
i;
dr[
1
]
=
"
列表项目
"
+
i.ToString();
dt.Rows.Add(dr);
}
return
dt;
}
protected
void
Button1_Click(
object
sender, EventArgs e)
{
//
读取TextBox控件内容
TextBox t = GridView1.Rows[0].Cells[0].FindControl("t1") as TextBox;
//
如果需要,重新绑定之
PerformDataBinde();
}
界面代码如下:
<
form id
=
"
form1
"
runat
=
"
server
"
>
<
div
>
<
asp:GridView ID
=
"
GridView1
"
runat
=
"
server
"
AutoGenerateColumns
=
"
False
"
>
<
HeaderStyle BackColor
=
"
#C0C0FF
"
/>
</
asp:GridView
>
<
asp:Button ID
=
"
Button1
"
runat
=
"
server
"
OnClick
=
"
Button1_Click
"
Text
=
"
Button
"
/></
div
>
</
form
>