ASP.NET怎么操作DataTable实例应用
程序员文章站
2024-03-06 17:04:38
有机会在博客园的博问频道上看到一个问题,《asp.net怎么操作datatable》: 如上图,左边的这个表是程序构建出来的,不是数据库表,怎么通过操作datatable手...
有机会在博客园的博问频道上看到一个问题,《asp.net怎么操作datatable》:
如上图,左边的这个表是程序构建出来的,不是数据库表,怎么通过操作datatable手段得到右边的四个表?
insus.net尝试做了一下,算是练习datatable的功力了。效果如下:
根据最初数据,insus.net在.aspx内放置了一个gridview,用来显示最开始的数据。
view code
<asp:gridview id="gridview1" runat="server" autogeneratecolumns="false">
<columns>
<asp:templatefield>
<headertemplate>
name
</headertemplate>
<itemtemplate>
<%# eval("name") %>
</itemtemplate>
</asp:templatefield>
<asp:templatefield>
<headertemplate>
quantity
</headertemplate>
<itemtemplate>
<%# eval("quantity") %>
</itemtemplate>
</asp:templatefield>
</columns>
</asp:gridview>
创建一个datatable,并填充数据:
view code
datatable getdata()
{
datatable table = new datatable();
table.columns.add("name", typeof(string));
table.columns.add("quantity", typeof(int));
table.rows.add("a", 1);
table.rows.add("a", 2);
table.rows.add("b", 2);
table.rows.add("b", 2);
table.rows.add("c", 1);
table.rows.add("c", 2);
table.rows.add("c", 3);
table.rows.add("c", 4);
return table;
}
然后为刚才创建的gridview绑定这个datatable:
view code
protected void page_load(object sender, eventargs e)
{
if (!ispostback)
{
data_binding();
}
}
private void data_binding()
{
this.gridview1.datasource = getdata();
this.gridview1.databind();
}
为了得到报表1,它有三个字段,名称(name),数量(amount)和行数(rowcount),insus.net还参考源数据,它还有一个数量(quantity)字段。因此,insus.net写了一个类别item,为以下导出报表作准备:
item
using system;
using system.collections.generic;
using system.linq;
using system.web;
/// <summary>
/// summary description for item
/// </summary>
namespace insus.net
{
public class item
{
private string _name;
private int _quantity;
private int _amount;
private int _rowcount;
public string name
{
get { return _name; }
set { _name = value; }
}
public int quantity
{
get { return _quantity; }
set { _quantity = value; }
}
public int amount
{
get { return _amount; }
set { _amount = value; }
}
public int rowcount
{
get { return _rowcount; }
set { _rowcount = value; }
}
public item()
{
//
// todo: add constructor logic here
//
}
public item(string name, int quantity)
{
this._name = name;
this._quantity = quantity;
}
public item(string name, int amount,int rowcount)
{
this._name = name;
this._amount = amount;
this._rowcount = rowcount;
}
}
}
ok,现在我们写一个报表,在.aspx放在一个按钮,以及一个gridview,来显示报表,注意一个字段的绑定。
view code
<asp:button id="buttonreport1" runat="server" text="报表1" onclick="buttonreport1_click" />
<asp:gridview id="gridview2" runat="server" autogeneratecolumns="false">
<columns>
<asp:templatefield>
<headertemplate>
name
</headertemplate>
<itemtemplate>
<%# eval("name") %>
</itemtemplate>
</asp:templatefield>
<asp:templatefield>
<headertemplate>
amount
</headertemplate>
<itemtemplate>
<%# eval("amount") %>
</itemtemplate>
</asp:templatefield>
<asp:templatefield>
<headertemplate>
rowcount
</headertemplate>
<itemtemplate>
<%# eval("rowcount") %>
</itemtemplate>
</asp:templatefield>
</columns>
</asp:gridview>
在.cs 写click事件:
view code
protected void buttonreport1_click(object sender, eventargs e)
{
sortedlist<string, item> _sl = new sortedlist<string, item>();
datatable otable = getdata();
foreach (datarow dr in otable.rows)
{
if (_sl.containskey(dr["name"].tostring()))
{
_sl[dr["name"].tostring()].amount += convert.toint32(dr["quantity"]);
_sl[dr["name"].tostring()].rowcount += 1;
}
else
{
item i = new item(dr["name"].tostring(), convert.toint32(dr["quantity"]), 1);
_sl.add(dr["name"].tostring(), i);
}
}
this.gridview2.datasource = _sl.values;
this.gridview2.databind();
}
第一份报表,大功告成,只要datatable数源数据有变化,报表也会随之变化。
接下来,完成第二个报表,在insus.net使用repeater包含repeater来实现。因此,前台html代码如下,其中第一个repeate内放置了一个hiddenfield,来存储名称(name)字段,当作子repeater的参考传入。
view code
<asp:button id="buttonreport2" runat="server" text="报表2" onclick="buttonreport2_click" />
<asp:repeater id="repeater1" runat="server" onitemdatabound="repeater1_itemdatabound">
<itemtemplate>
<asp:hiddenfield id="hiddenfield1" runat="server" value='<%# container.dataitem %>' />
<asp:repeater id="repeater2" runat="server">
<headertemplate>
<table border="1" cellspacing="0" cellpadding="5" style="margin: 10px; border-collapse: collapse;">
<tr>
<td>name</td>
<td>quantity</td>
</tr>
</headertemplate>
<itemtemplate>
<tr>
<td><%# eval("name") %></td>
<td><%# eval("quantity") %></td>
</tr>
</itemtemplate>
<footertemplate>
</table>
</footertemplate>
</asp:repeater>
</itemtemplate>
</asp:repeater>
首先,我们需要从datatable,获取名称(name)唯一的记录存储起来,作为第一个repeate控件的数据集数据源。
view code
protected void buttonreport2_click(object sender, eventargs e)
{
this.repeater1.datasource = names();
this.repeater1.databind();
}
list<string> names()
{
list<string> t = new list<string>();
datatable otable = getdata();
foreach (datarow dr in otable.rows)
{
if (!t.contains(dr["name"].tostring()))
t.add(dr["name"].tostring());
}
return t;
}
我们还要写第二个repeater控件的数据源:
view code
list<item> getdatabyname(string name)
{
list<item> o = new list<item>();
datatable otable = getdata();
foreach (datarow dr in otable.rows)
{
if (name == dr["name"].tostring())
{
item i = new item(dr["name"].tostring(), convert.toint32(dr["quantity"]));
o.add(i);
}
}
return o;
}
为第二个repeater控件绑定数据源,在绑写之前,得先找到这个控件,因此,你需要在第一个repeater控件写onitemdatabound="repeater1_itemdatabound"事件:
view code
protected void repeater1_itemdatabound(object sender, repeateritemeventargs e)
{
if (e.item.itemtype == listitemtype.item || e.item.itemtype == listitemtype.alternatingitem)
{
if (e.item.findcontrol("hiddenfield1") != null && e.item.findcontrol("repeater2") != null)
{
var hiddenfield = e.item.findcontrol("hiddenfield1") as hiddenfield;
var repeater = e.item.findcontrol("repeater2") as repeater;
repeater.datasource = getdatabyname(hiddenfield.value);
repeater.databind();
}
}
}
如上图,左边的这个表是程序构建出来的,不是数据库表,怎么通过操作datatable手段得到右边的四个表?
insus.net尝试做了一下,算是练习datatable的功力了。效果如下:
根据最初数据,insus.net在.aspx内放置了一个gridview,用来显示最开始的数据。
复制代码 代码如下:
view code
<asp:gridview id="gridview1" runat="server" autogeneratecolumns="false">
<columns>
<asp:templatefield>
<headertemplate>
name
</headertemplate>
<itemtemplate>
<%# eval("name") %>
</itemtemplate>
</asp:templatefield>
<asp:templatefield>
<headertemplate>
quantity
</headertemplate>
<itemtemplate>
<%# eval("quantity") %>
</itemtemplate>
</asp:templatefield>
</columns>
</asp:gridview>
创建一个datatable,并填充数据:
复制代码 代码如下:
view code
datatable getdata()
{
datatable table = new datatable();
table.columns.add("name", typeof(string));
table.columns.add("quantity", typeof(int));
table.rows.add("a", 1);
table.rows.add("a", 2);
table.rows.add("b", 2);
table.rows.add("b", 2);
table.rows.add("c", 1);
table.rows.add("c", 2);
table.rows.add("c", 3);
table.rows.add("c", 4);
return table;
}
然后为刚才创建的gridview绑定这个datatable:
复制代码 代码如下:
view code
protected void page_load(object sender, eventargs e)
{
if (!ispostback)
{
data_binding();
}
}
private void data_binding()
{
this.gridview1.datasource = getdata();
this.gridview1.databind();
}
为了得到报表1,它有三个字段,名称(name),数量(amount)和行数(rowcount),insus.net还参考源数据,它还有一个数量(quantity)字段。因此,insus.net写了一个类别item,为以下导出报表作准备:
复制代码 代码如下:
item
using system;
using system.collections.generic;
using system.linq;
using system.web;
/// <summary>
/// summary description for item
/// </summary>
namespace insus.net
{
public class item
{
private string _name;
private int _quantity;
private int _amount;
private int _rowcount;
public string name
{
get { return _name; }
set { _name = value; }
}
public int quantity
{
get { return _quantity; }
set { _quantity = value; }
}
public int amount
{
get { return _amount; }
set { _amount = value; }
}
public int rowcount
{
get { return _rowcount; }
set { _rowcount = value; }
}
public item()
{
//
// todo: add constructor logic here
//
}
public item(string name, int quantity)
{
this._name = name;
this._quantity = quantity;
}
public item(string name, int amount,int rowcount)
{
this._name = name;
this._amount = amount;
this._rowcount = rowcount;
}
}
}
ok,现在我们写一个报表,在.aspx放在一个按钮,以及一个gridview,来显示报表,注意一个字段的绑定。
复制代码 代码如下:
view code
<asp:button id="buttonreport1" runat="server" text="报表1" onclick="buttonreport1_click" />
<asp:gridview id="gridview2" runat="server" autogeneratecolumns="false">
<columns>
<asp:templatefield>
<headertemplate>
name
</headertemplate>
<itemtemplate>
<%# eval("name") %>
</itemtemplate>
</asp:templatefield>
<asp:templatefield>
<headertemplate>
amount
</headertemplate>
<itemtemplate>
<%# eval("amount") %>
</itemtemplate>
</asp:templatefield>
<asp:templatefield>
<headertemplate>
rowcount
</headertemplate>
<itemtemplate>
<%# eval("rowcount") %>
</itemtemplate>
</asp:templatefield>
</columns>
</asp:gridview>
在.cs 写click事件:
复制代码 代码如下:
view code
protected void buttonreport1_click(object sender, eventargs e)
{
sortedlist<string, item> _sl = new sortedlist<string, item>();
datatable otable = getdata();
foreach (datarow dr in otable.rows)
{
if (_sl.containskey(dr["name"].tostring()))
{
_sl[dr["name"].tostring()].amount += convert.toint32(dr["quantity"]);
_sl[dr["name"].tostring()].rowcount += 1;
}
else
{
item i = new item(dr["name"].tostring(), convert.toint32(dr["quantity"]), 1);
_sl.add(dr["name"].tostring(), i);
}
}
this.gridview2.datasource = _sl.values;
this.gridview2.databind();
}
第一份报表,大功告成,只要datatable数源数据有变化,报表也会随之变化。
接下来,完成第二个报表,在insus.net使用repeater包含repeater来实现。因此,前台html代码如下,其中第一个repeate内放置了一个hiddenfield,来存储名称(name)字段,当作子repeater的参考传入。
复制代码 代码如下:
view code
<asp:button id="buttonreport2" runat="server" text="报表2" onclick="buttonreport2_click" />
<asp:repeater id="repeater1" runat="server" onitemdatabound="repeater1_itemdatabound">
<itemtemplate>
<asp:hiddenfield id="hiddenfield1" runat="server" value='<%# container.dataitem %>' />
<asp:repeater id="repeater2" runat="server">
<headertemplate>
<table border="1" cellspacing="0" cellpadding="5" style="margin: 10px; border-collapse: collapse;">
<tr>
<td>name</td>
<td>quantity</td>
</tr>
</headertemplate>
<itemtemplate>
<tr>
<td><%# eval("name") %></td>
<td><%# eval("quantity") %></td>
</tr>
</itemtemplate>
<footertemplate>
</table>
</footertemplate>
</asp:repeater>
</itemtemplate>
</asp:repeater>
首先,我们需要从datatable,获取名称(name)唯一的记录存储起来,作为第一个repeate控件的数据集数据源。
复制代码 代码如下:
view code
protected void buttonreport2_click(object sender, eventargs e)
{
this.repeater1.datasource = names();
this.repeater1.databind();
}
list<string> names()
{
list<string> t = new list<string>();
datatable otable = getdata();
foreach (datarow dr in otable.rows)
{
if (!t.contains(dr["name"].tostring()))
t.add(dr["name"].tostring());
}
return t;
}
我们还要写第二个repeater控件的数据源:
复制代码 代码如下:
view code
list<item> getdatabyname(string name)
{
list<item> o = new list<item>();
datatable otable = getdata();
foreach (datarow dr in otable.rows)
{
if (name == dr["name"].tostring())
{
item i = new item(dr["name"].tostring(), convert.toint32(dr["quantity"]));
o.add(i);
}
}
return o;
}
为第二个repeater控件绑定数据源,在绑写之前,得先找到这个控件,因此,你需要在第一个repeater控件写onitemdatabound="repeater1_itemdatabound"事件:
复制代码 代码如下:
view code
protected void repeater1_itemdatabound(object sender, repeateritemeventargs e)
{
if (e.item.itemtype == listitemtype.item || e.item.itemtype == listitemtype.alternatingitem)
{
if (e.item.findcontrol("hiddenfield1") != null && e.item.findcontrol("repeater2") != null)
{
var hiddenfield = e.item.findcontrol("hiddenfield1") as hiddenfield;
var repeater = e.item.findcontrol("repeater2") as repeater;
repeater.datasource = getdatabyname(hiddenfield.value);
repeater.databind();
}
}
}
上一篇: Android图片缓存之Lru算法(二)
下一篇: 深入解析java HashMap实现原理