I have the opportunity to see a question on the blog page, ASP. NET DataTable:
For example, the table on the left is built by a program, not a database table. How can we obtain the four tables on the right through the DataTable operation?
Insus. NET tried to do it, which is the skill of practicing DataTable. The effect is as follows:
According to the initial data, Insus. NET places a Gridview in. aspx to display the initial data.
Copy codeThe Code is as follows: 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>
Create a able and fill in the data:Copy codeThe Code is as follows: 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;
}
Then bind the DataTable to the created Gridview:Copy codeThe Code is as follows: 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 ();
}
To get Report 1, it has three fields: Name, number, Rowcount, and Insus. NET also references the source data. It also has a Quantity field. Therefore, Insus. NET writes a category Item to prepare for the following export reports:Copy codeThe Code is as follows: 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. Now we write a report, put it in a button in. aspx, and a GridView to display the report. Pay attention to the binding of a field.Copy codeThe Code is as follows: View Code
<Asp: Button ID = "ButtonReport1" runat = "server" Text = "Report 1" OnClick = "buttonreport#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>
Write the click Event in. cs:Copy codeThe Code is as follows: View Code
Protected void buttonreport#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 ();
}
The first report is successful. As long as the DataTable data source changes, the report also changes.
Next, complete the second report and use Repeater to include Repeater in Insus. NET. Therefore, the front-end Html code is as follows. A HiddenField is placed in the first Repeate to store the Name field, which is passed as a reference for the subrepeater.Copy codeThe Code is as follows: View Code
<Asp: Button ID = "ButtonReport2" runat = "server" Text = "Report 2" OnClick = "ButtonReport2_Click"/>
<Asp: Repeater ID = "Repeater1" runat = "server" OnItemDataBound = "repeaterincluitemdatabound">
<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>
First, we need to obtain a unique record with the Name from the DataTable and store it as the data source of the first Repeate control.Copy codeThe Code is as follows: 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;
}
We also need to write the data source of the second Repeater control:Copy codeThe Code is as follows: 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;
}
To bind a data source to the second Repeater control, you must first find the control before binding. Therefore, you need to write the OnItemDataBound = "repeaterincluitemdatabound" event in the first Repeater control:Copy codeThe Code is as follows: View Code
Protected void repeaterincluitemdatabound (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 ();
}
}
}