Advanced DataGrid


In the previous sections, we examined how to accomplish some common tasks using the DataGrid’s built-in support. In this section, we’ll look at some tasks that are a little more esoteric and require a bit more code, taking advantage of the DataGrid control’s flexibility.

Adding Data

As you’ve seen, the DataGrid has built-in support for updating data, offers a simple way to work with selected data, and makes deleting data easy. But when you deal with dynamic Web applications, you need to allow the user to add new data. To accomplish this, you add a Button control outside of the DataGrid, and in the associated Click event handler you add a new row to the data source of the DataGrid. At the same time, you set the EditItemIndex to the new item and call DataBind. The user is presented with the familiar DataGrid editing interface to add values for the new row. Notice in Code Listing 3-16 that we modified Code Listing 3-13 to include the ability to add a new row. The CancelCommand event handler has been modified to remove a row from the DataSet that has not been updated. When the user clicks the Add button, the CancelCommand event handler is invoked explicitly. This prevents you from adding a new empty row when the previous row is not completed. Actually, the incomplete row is removed and then a new row with the same defaults is added again, but to the user the result is the same—the incomplete data is not persisted.

Code Listing 3-16: DataGridAdd.aspx

start example
 <%@Import namespace="System.Data" %>
<script language="C#" runat="server">
DataTable data;
protected void Page_Load(object o, EventArgs e) {
GetData();
datagrid1.DataSource = data;
if(!IsPostBack) {
datagrid1.DataBind();
}
}

DataTable GetData() {
data = Session["data"] as DataTable;
if(data != null) {
return data;
}
data = new DataTable();

DataColumn primaryColumn
= new DataColumn("carid", typeof(Int32));
data.Columns.Add(primaryColumn);
data.Columns.Add(new DataColumn("year", typeof(Int32)));
data.Columns.Add(new DataColumn("make", typeof(string)));
data.Columns.Add(new DataColumn("model", typeof(string)));
DataRow dr;
dr = data.NewRow();
dr[0] = 1; dr[1] = 1998; dr[2] = "Isuzu"; dr[3] = "Trooper";
data.Rows.Add(dr);
dr = data.NewRow();
dr[0] = 2; dr[1] = 2000; dr[2] = "Honda"; dr[3] = "Civic";
data.Rows.Add(dr);

DataColumn[] primaryColumns = new DataColumn[1];
primaryColumns[0] = primaryColumn;
data.PrimaryKey = primaryColumns;

Session["data"] = data;
return data;
}

protected void StartAdd(object o, EventArgs e) {
OnCancel(null, null);
DataRow dr = data.NewRow();
dr["carid"] = data.Rows.Count + 1;
dr["year"] = 2000;
dr["make"] = "";
dr["model"] = "";
data.Rows.InsertAt(dr, 0);
datagrid1.EditItemIndex = data.Rows.Count - 1;
datagrid1.DataBind();
}

protected void OnEdit(object o, DataGridCommandEventArgs e) {
datagrid1.EditItemIndex = e.Item.ItemIndex;
datagrid1.DataBind();
}

protected void OnCancel(object o, DataGridCommandEventArgs e) {
DataRow dr = data.Rows.Find(data.Rows.Count);
if((int)dr["year"] < 1930 || (int)dr["year"] > 2004
|| dr["make"] == "" || dr["model"] == "") {
Response.Write("removing row");
data.Rows.Remove(dr);
}
datagrid1.EditItemIndex = -1;
datagrid1.DataBind();
}

protected void OnUpdate(object o, DataGridCommandEventArgs e) {
int year;
try {
year = Int32.Parse((
(TextBox)e.Item.Cells[2].Controls[0]).Text);
}
catch(System.FormatException fe) {
Response.Write(
"Invalid year specified. Update not completed");
return;
}
string make = ((TextBox)e.Item.Cells[3].Controls[0]).Text;
string model = ((TextBox)e.Item.Cells[4].Controls[0]).Text;
DataRow row = data.Rows.Find(e.Item.Cells[1].Text);
if(row != null) {
row["year"] = year.ToString();
row["make"] = make;
row["model"] = model;

}
data.AcceptChanges();
datagrid1.EditItemIndex = -1;
datagrid1.DataBind();
Session["data"] = data;
}
</script>
<form runat="server">
<asp:DataGrid runat="server" DataKeyField="carid"
AutoGenerateColumns="false" OnEditCommand="OnEdit"
OnCancelCommand="OnCancel" OnUpdateCommand="OnUpdate" >
<Columns>
<asp:EditCommandColumn EditText="Edit"
CancelText="Cancel" UpdateText="Update" />
<asp:boundcolumn DataField="carid" ReadOnly="true"
HeaderText="id" />
<asp:BoundColumn DataField="year" HeaderText="year" />
<asp:BoundColumn DataField="make" HeaderText="make" />
<asp:BoundColumn DataField="model" HeaderText="model" />
</Columns>
</asp:DataGrid><br/>
<asp:button runat="server" type="submit"
OnClick="StartAdd" Text="Add"/>
</form>
end example

Summarizing Data

In the previous code examples, we included header text for the columns in the column declarations. The DataGrid also supports the inclusion of a footer row, and this is enabled by setting the ShowFooter property to true. The DataGrid creates the space for the footer information automatically, but it does not fill the data in. The summary information can be calculated on the fly as each item is added and then set explicitly when the footer item is added. The footer item is added after all the items and alternating items. Code Listing 3-17 illustrates how to summarize data by adding an ItemCreated event handler and then accumulate the value from the items as they are added. Notice that when the FooterItem is added, the contents of the TableCell are set explicitly with the markup and the total.

Code Listing 3-17: DataGridSummary.aspx

start example
 <%@Import namespace="System.Data" %>
<script language="C#" runat="server">
protected void Page_Load(object o, EventArgs e) {
if(!IsPostBack) {
datagrid.DataSource = GetData();
DataBind();
}
}

DataView GetData() {
DataTable data = new DataTable();
data.Columns.Add(new DataColumn("aNumber", typeof(Int32)));
DataRow dr;
dr = data.NewRow(); dr[0] = "70"; data.Rows.Add(dr);
dr = data.NewRow(); dr[0] = "58"; data.Rows.Add(dr);
dr = data.NewRow(); dr[0] = "62"; data.Rows.Add(dr);
dr = data.NewRow(); dr[0] = "54"; data.Rows.Add(dr);
dr = data.NewRow(); dr[0] = "57"; data.Rows.Add(dr);
dr = data.NewRow(); dr[0] = "50"; data.Rows.Add(dr);
dr = data.NewRow(); dr[0] = "52"; data.Rows.Add(dr);
dr = data.NewRow(); dr[0] = "49"; data.Rows.Add(dr);
dr = data.NewRow(); dr[0] = "46"; data.Rows.Add(dr);
DataView view = new DataView(data);
return view;
}

int total;
void DataGrid_ItemCreated(object o, DataGridItemEventArgs e) {
if((e.Item.ItemType == ListItemType.Item) ||
(e.Item.ItemType == ListItemType.AlternatingItem)) {
total += (int)(DataBinder.Eval(e.Item.DataItem, "aNumber"));
return;
}
if(e.Item.ItemType == ListItemType.Footer) {
e.Item.Cells[0].Text = "<b><i>" + total + "</i></b>";
}
}
</script>
<form runat="server">
<asp:DataGrid runat="server"
AutoGenerateColumns="false"
OnItemCreated="DataGrid_ItemCreated" ShowFooter="true">
<Columns>
<asp:BoundColumn DataField="aNumber"
HeaderText="Number"/>
</Columns>
</asp:DataGrid>
</form>
end example

Note

Reflecting on the individual items has an impact on performance. For large sets of data with numerous columns to summarize, leveraging the database directly for calculated values might be more efficient.




Microsoft ASP. NET Coding Strategies with the Microsoft ASP. NET Team
Microsoft ASP.NET Coding Strategies with the Microsoft ASP.NET Team (Pro-Developer)
ISBN: 073561900X
EAN: 2147483647
Year: 2005
Pages: 144

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net