分享:DataGrid,动态模板列,ITemplate

wincarf 2003-12-11 08:25:41
终于解决了一个问题,写出来大家分享。
在使用DataGrid捕获数据时很可能会遇到这样一种情况:数据列是根据数据库记录变化的,为了解决这个问题必须使DataGrid的列是根据数据库中的记录动态创建。有两个方法可以解决:
一是将数据读到DataTable中,由DataGrid根据DataTable自动创建列,并使用按钮列来使行进入编辑状态。这是一个简单的办法。但是有一个问题:数据输入比较麻烦,用户要点击edit按钮,才能使一行进入编辑状态(出现文本框)输入数据,并且由于每次进入编辑状态实际上都要postback回服务器端,效率也不好。
因此在这种情况下,一般希望使用模板列来实现。因此第二各方法就是动态构造模板列。
动态构造模板列首先要实现Itemplate接口,一个只使用文本框作为模板的实现可以如下:
public class CTemplateCol:ITemplate
{
private string colname;
TextBox l;
public CTemplateCol(string cname)
{
colname=cname;
}

//must implement following method
public void InstantiateIn(Control container)
{
l = new TextBox();
l.ID=colname;
l.CssClass="boxs";
l.Width=60;
l.DataBinding +=
new EventHandler(this.OnDataBinding);
container.Controls.Add(l);
}
public void OnDataBinding(object sender, EventArgs e)
{
TextBox l = (TextBox) sender;
DataGridItem container =
(DataGridItem) l.NamingContainer;
l.Text =
((DataRowView)
container.DataItem)[colname].ToString();
}
}
在我的项目里,单击button1,会根据用户选择的日期和报表动态构造一个DataGrid相关代码如下:
foreach(String typename in typesList)
{
dtb.Columns.Add(typename);
TemplateColumn tc1=new TemplateColumn();
tc1.ItemTemplate=new CTemplateCol(typename);
tc1.HeaderText=typename;
DataGrid1.Columns.Add(tc1);
}
然后只要绑定好datasource调用databind就可以完成显示了。
用户在页面上输入了数据后单击button2,就会将数据传回来。开始困扰我的地方在于在button2的事件里面检测datagrid是检测不到动态创建的模板列的,只有几个固定的列存在。后来我查到应该在页面回传时再次创建动态模板列,而且必须在page_load事件中完成这个工作,于是我在page_load事件中加入了以下代码:
String sourcectrl=Request.Form["Button2"];
if(sourcectrl=="提交数据")
{
DataTable dtb=(DataTable)ViewState["UpdateTable"];//以前的数据
ArrayList types=(ArrayList)ViewState["TypeList"];//列名
if((dtb!=null)&&(types!=null))
{
foreach(String typename in types)
{
TemplateColumn tc1=new TemplateColumn();
tc1.ItemTemplate=new CTemplateCol(typename); tc1.HeaderText=typename;
DataGrid1.Columns.Add(tc1);
}
DataGrid1.DataSource=dtb;
DataGrid1.DataBind();
}
}
保证在button2点击后造成的postback中重新构造动态模板列,有趣的是使用了以前存入viewstate的datatable的数据来初始化DataGrid的数据源并绑定了数据,表面看来这回覆盖掉用户在网页上输入的数据,但实际上这是正确的选择,否则反而得不到用户输入的数据。
而在button2的click事件中则可以接收用户输入:
int i=-1;
foreach (DataGridItem dgi in DataGrid1.Items)
{
i++;
TextBox t;
foreach(String typename in types)
{
t=null;
for(int j=0;j<dgi.Cells.Count;j++)
{
t=(TextBox)dgi.Cells[j].FindControl(typename);
if(t!=null)break;
}
if(t!=null)
{
try
{
if(t.Text!="")dtb.Rows[i][typename]=Convert.ToDouble(t.Text);
}
catch(Exception)
{
Label2.Text="数据输入错误!";
Label2.Visible=true;
return;
}
}
}
用户输入的新的数据就保存到datatable中了;
以上就是整个处理过程,与大家分享,如果大家有更好的方法,请一起讨论
...全文
73 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
publicX 2003-12-13
  • 打赏
  • 举报
回复
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon/html/vbtskcreatingtemplatesprogrammaticallyindatagridcontrol.asp
cm8983 2003-12-13
  • 打赏
  • 举报
回复
收藏!
wincarf 2003-12-13
  • 打赏
  • 举报
回复
viewstate["anyname"]=dtb;//dtb is a datatable
chenlh 2003-12-11
  • 打赏
  • 举报
回复
请问viewstate中如何保存datatable ??

kerling78 2003-12-11
  • 打赏
  • 举报
回复
好东西,收藏!

62,074

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧