
C# ПІДРУЧНИКИ / c# / Hungry Minds - ASP.NET Bible VB.NET & C#
.pdf
must be set to a field defined in the data source. When the DataGrid is bound to the data source in the previous example, Figure 10-7 is displayed when executed in the browser.
Figure 10-7: ButtonColumn.aspx, as displayed in Internet Explorer
You could just as easily have specified the LinkButton property to display a column of hyperlinks from your data source. If you click one of the buttons, the form is posted back to itself. Take a look at the following HTML fragment from ButtonColumn.aspx:
<td>
<input type="submit" name="Custom:ctrl2:ctrl0" value="Button 0" />
</td>
When the ButtomColumn type is rendered on the browser, each td element in the table is generated as a Submit button. What if you want to add an event handler for each button that performs some type of action when the button is clicked? You can do that by adding the OnItemCommand event handler to the CommandName property of the button. The following code demonstrates how to wire up the OnItemCommand event for the DataGrid control:
...
protected void Custom_Click(Object sender, DataGridCommandEventArgs e) { Msg.Text = "You
clicked Integer " + e.Item.Cells[1].Text; }
...
<form method="post" runat="server">
<asp:DataGrid
ID="Custom"
AutoGenerateColumns="false"
ShowHeader="True"
OnItemCommand="Custom_Click"
RunAt="server">
<HeaderStyle
BackColor="#6699cc" />
<columns>
<asp:ButtonColumn
ButtonType="PushButton"
Text="Click"

HeaderText="Action"
CommandName="PushButton" />
<asp:BoundColumn
DataField="Integer"
HeaderText="Integer" />
</columns>
</asp:DataGrid>
<br>
<asp:Label ID="Msg" text="Click a column button." Runat="server" />
</form>
The script code defines the Custom_Click event, which is called every time a button on the grid is clicked. This event takes two arguments: the Sender parameter, which is of type Object, and the DataGridCommandEventArgs as the second parameter.
The DataGridCommandEventArgs argument has the following properties that can be inspected:
§CommandArgument: This property gets the argument passed from the command.
§CommandName: This property gets the name of the command.
§CommandSource: This property gets the source of the command.
§Item: This property gets the item that is selected in the DataGrid control. In the preceding example, the CommandName is "PushButton" and the Item is a
DataGridItem that represents the selected item in the control. It is also used to access the properties of the selected item.
The second code fragment has the HTML to set up the button to handle the click event. The only line you are concerned with here is the CommandName property, which identifies the button that is clicked and is passed to the CustomClick event in the
DataGridCommandArgs event.
When you launch your browser and execute the ButtonColumn2.aspx page, your page should look like Figure 10-8.
Figure 10-8: ButtonColumn2.aspx, as displayed in Internet Explorer
Click any one of the buttons, and a message displays in the Label control at the bottom of the page.

EditColumn Class
Next on the list is the EditColumn class. When used in the DataGrid control, the Web page developer can perform any type of editing on any data item within the grid. This is a powerful addition to the Web developer's toolbox. In the past, this type of editing would require a great deal of code to accomplish. With .NET, you only need to wire up the Cancel, Edit, and Update events and set the appropriate properties. In this example, you are going to read in some data from an XML file and then allow the user to edit the data. Launch your browser and navigate to EditColumn.aspx; your screen should look like Figure 10-9.
Figure 10-9: EditColumn.aspx, as displayed in Internet Explorer
Before you review the code, walk through editing one of the items in the grid. Click Edit on any of the rows in the grid. Notice that the other columns change to TextBox controls so that you can edit the data. Also, the Edit button changes to the Update and Cancel buttons. At this point, you can change the data in any of the TextBox controls and then choose to update or cancel the changes. If you have any columns that are ReadOnly, you can flag that column, and editing will not be allowed on that data item.
Note In this example, you are not going to save the changes back to the XML file to preserve the integrity of the XML file.
The EditColumn.aspx file is generated by the following code:
<%@ Import Namespace="System.Data" %>
<html>
<head>
<script language="C#" runat="server">
DataSet ds = new DataSet();
void Page_Load(Object sender, EventArgs e) {
ds.ReadXml(Page.MapPath("data.xml"));
if (!IsPostBack)
BindData();
}
void EditColumn_Edit(Object sender, DataGridCommandEventArgs e) { EditColumn.EditItemIndex = e.Item.ItemIndex;
BindData();
}
void EditColumn_Cancel(Object sender, DataGridCommandEventArgs e) { EditColumn.EditItemIndex = -1;
BindData();
}
void EditColumn_Update(Object sender, DataGridCommandEventArgs e) {
String Name = e.Item.Cells[1].Text;
TextBox Birthday = (TextBox)e.Item.Cells[2].Controls[0];
TextBox Phone = (TextBox)e.Item.Cells[3].Controls[0];
ds.Tables[0].DefaultView.RowFilter = "Name='" + Name + "'"; if (ds.Tables[0].DefaultView.Count > 0 )
ds.Tables[0].DefaultView.Delete(0);
ds.Tables[0].DefaultView.RowFilter = "";
DataRow dr;
dr = ds.Tables[0].NewRow(); dr[0] = Name;
dr[1] = Birthday.Text; dr[2] = Phone.Text;
ds.Tables[0].Rows.Add(dr);
EditColumn.EditItemIndex = -1;
BindData();
}
void BindData() { EditColumn.DataSource = ds; EditColumn.DataBind();
}
</script>
</head>
<body>
<img src="logo.gif"> <br>
<font face="verdana" size="5">DataGrid Example with the Edit Column...</font> <hr>
<form runat="server">
<asp:DataGrid id="EditColumn" runat="server" BorderColor="#6699cc"
BorderWidth="1"
CellPadding="1"
Font-Name="verdana"
Font-Size="10pt"
HeaderStyle-BackColor="#6699cc"
OnEditCommand="EditColumn_Edit"
OnCancelCommand="EditColumn_Cancel"
OnUpdateCommand="EditColumn_Update"
AutoGenerateColumns="false">
<Columns>
<asp:EditCommandColumn
ButtonType="LinkButton"
EditText="Edit"
CancelText="Cancel"
UpdateText="Update"
ItemStyle-Wrap="false" HeaderText="Edit Command Column" HeaderStyle-Wrap="false"/> <asp:BoundColumn HeaderText="Name" ReadOnly="true" DataField="Name"/> <asp:BoundColumn HeaderText="Birthday" DataField="BirthDay"/> <asp:BoundColumn HeaderText="Phone" DataField="Phone"/>
</Columns>
</asp:DataGrid>
</form>
</body>
</html>
The presentation code will be discussed first, followed by the event handlers. Like the other column classes discussed, the EditColumn class is enclosed within the
<columns> </columns> tags of the DataGrid control. Next, you need to specify which button type to use; the ButtonType property can be set to PushButton or
LinkButton. The EditText, CancelText, and UpdateText properties can be set to any string value that you choose. These string values are displayed either as hyperlinks or as push buttons, depending on the setting of the ButtonType property. Most of the other properties for the EditColumn class are for formatting the display output.
Now that the properties are set, turn your attention to wiring up the event handlers for the Edit, Cancel, and Update buttons. When the user clicks the Edit button on the grid, it
raises the EditCommand event, which then passes the DataGridCommandEventArgs class as a parameter. From there, you can extract which item was selected in the grid and then set the EditItemIndex to the selected item. Look at the following line of code:
EditColumn.EditItemIndex = e.Item.ItemIndex;
After you set this property, you call the BindData method to rebind your data and display the text boxes for editing.
The CancelCommand event is raised when the user decides to cancel the edits and return the grid to its previous values. Once again, this event takes the DataGridCommandEventArgs class as a parameter. You only need to set the EditItemIndex to -1 to flag that you are aborting all edits on the grid.
Most of the code that you need to write is for the UpdateEvent. You need to take several steps, each of which is described next. First, you need to extract the values from the grid, as in the following lines of code:
String Name = e.Item.Cells[1].Text;
TextBox Birthday = (TextBox)e.Item.Cells[2].Controls[0];
TextBox Phone = (TextBox)e.Item.Cells[3].Controls[0];
You extract the name to a string value for a couple of reasons. Because the Name field is flagged as ReadOnly in the columns tag, you can't edit this field. In addition, you are going to use this value as the filter in the data table to find the selected row. The next two lines of code extract the values from the grid and cast them to TextBox controls. You need to save these values because you are going to be deleting the selected row from the grid. In the following lines of code, you filter the data table for the selected row and then delete it (we are not actually deleting the row from the DataSource):
ds.Tables[0].DefaultView.RowFilter = "Name='" + Name + "'";
if (ds.Tables[0].DefaultView.Count > 0 )
ds.Tables[0].DefaultView.Delete(0);
ds.Tables[0].DefaultView.RowFilter = "";
Notice that you check to make sure the Count property of the DefaultView is greater than zero before you delete the row. Then, you set the RowFilter property back to an empty string. Finally, you add the new values to a new data row and then add this row to the data table. Call the BindData method to refresh the grid and display your new values.
Note
HyperLinkColumn Class
The last column class to discuss is the HyperLinkColumn class. This column type is rendered as an anchor tag by the browser. Use the HyperLink control to create a link to another Web page. The HyperLink control is typically displayed as text specified by the Text property. It can also be displayed as an image specified by the ImageUrl property.
The following are the commonly used properties of the HyperLink control:
§DataNavigateUrlField: Indicates the field name to set or get from a data source to bind to the URL
§DataNavigateUrlFormatString: Indicates the string to get or set that specifies the display format for the URL
§DataTextField: Indicates the a field from the data source that is used as the text caption of the hyperlinks
§DataTextFormatString: Indicates the string to get or set that specifies the display format for the text caption of the hyperlinks
Take a look at the following code in the HyperLink column example: <%@ Import NameSpace="System.Data" %>
<html>
<head>
<title>Hungry Minds Chapter 9...</title> <script language="C#" runat="server">
DataSet ds = new DataSet();
void Page_Load(Object sender, EventArgs e) {
ds.ReadXml(Page.MapPath("data.xml")) ; BindData();
if (Request.QueryString["birthday"] != null ) msg.Text = "Your birthday is in " + Request.QueryString["Birthday"];
}
void BindData() { HyperLink.DataSource = ds; HyperLink.DataBind();
}
</script>
</head>
<body>
<img src="logo.gif"> <br>
<font face="verdana" size="5">DataGrid Example with the HyperLink Column...</font> <hr>
<form method="post" runat="server"> <asp:DataGrid
ID="HyperLink"
AutoGenerateColumns="false"
ShowHeader="True"
RunAt="server">
<HeaderStyle BackColor="#6699cc" />
<columns>

<asp:HyperLinkColumn
DataNavigateUrlFormatString="HyperLinkColumn.ASPX?Birthday={0}"
DataNavigateUrlField="Birthday"
DataTextField="Name"
HeaderText="Name" />
</columns>
</asp:DataGrid>
<asp:Label ID="msg" Runat="server" />
</form>
<hr>
</body>
</html>
In the preceding code, the DataNavigateUrlFormatString is where you specify what URL to navigate to when the user selects an item. You can also add parameters to the query string. Notice that the syntax for specifying the Birthday parameter is enclosed in parentheses. If you had other arguments to pass on the query string line, you would use a comma-separated list. The next property is the DataNavigateUrlField, which indicates the specific field in the DataSource to use as the parameter in the query string. In the preceding example, this field is the Birthday field. Next is the DataTextField property, which is the actual field that is displayed as the data item in the grid column. This can be any field from the specified DataSource. Finally, the HeaderText property sets the column heading in your grid.
Launch your browser and navigate to HyperLinkColumn.aspx; the screen should look like Figure 10-10.
Figure 10-10: HyperLinkColumn.aspx, as displayed in Internet Explorer Click one of the names in the list, when the form is reloaded we check the
Request.QueryString for the Birthday parameter. If the birthday parameters exist, the birthday message is displayed in the asp:Label control.
As you can see from the examples, the .NET DataGrid server control brings a lot of functionality to the table for the Web page developer. Instead of being concerned with writing the application logic, the Web developer can concentrate on the presentation of the page. The previous sections have looked at the most commonly used properties of each of the column controls that can be used in the DataGrid control so that you can get up to speed quickly using them in your own code. Before you wrap up this chapter on the DataGrid control, the following sections walk you through a few examples for sorting and paging data in the grid.
Paging Grid Data
Paging came along with the introduction of the DataGrid control. This simple event actually involves quite a bit of work behind the scenes. When the user requests the next page of data, the browser makes a round trip to the server to determine the next page of data, and then renders the next page of data on the client. With .NET, this is now a trivial task, requiring only that you set a few properties and wire up one event. If you want to handle your own paging, you can do that by setting the CustomPaging property.
The following code automatically generates the data items from the data source and then sets the style of paging:
<%@ Import NameSpace="System.Data" %>
<html>
<head>
<title>Hungry Minds Chapter 9...</title>
<script language="C#" runat="server">
DataSet ds = new DataSet();
void Page_Load(Object sender, EventArgs e) {
if (!IsPostBack)
BindData();
}
void LoadDataSource() {
ds.ReadXml(Page.MapPath("data.xml")) ;
}
void BindData() {
LoadDataSource();
Paging.DataSource = ds;
Paging.DataBind();
}
void PageIndexChanged(Object sender, DataGridPageChangedEventArgs e) {
Paging.CurrentPageIndex = e.NewPageIndex;
BindData();
}
</script>
</head>
<body>
<img src="logo.gif">
<br>
<font face="verdana" size="5">DataGrid Paging Example...</font>

<hr>
<form method="post" runat="server" ID="Form1">
<asp:DataGrid
ID="Paging"
AutoGenerateColumns="true"
OnPageIndexChanged="PageIndexChanged"
ShowHeader="True"
BorderColor="#6699cc"
BorderWidth="1"
CellPadding="1"
Font-Name="verdana"
Font-Size="10pt"
HeaderStyle-BackColor="#6699cc"
AllowPaging="true"
PageSize="4"
PagerStyle-NextPageText="[Next Page]"
PagerStyle-PrevPageText="[Previous Page]"
PagerStyle-HorizontalAlign="center"
RunAt="server">
</asp:DataGrid>
</form>
<hr>
</body>
</html>
Launch your browser and navigate to DataGridPaging.aspx; the screen should look like Figure 10-11.
Figure 10-11: DataGridPaging.aspx, as displayed in Internet Explorer
Select the Next or Previous hyperlink at the bottom of the data grid. The next or previous page of data is fetched from the data source and displayed in the grid. You can adjust the number of pages to display, the style of the paging buttons, and determine the number of pages in your data source. With the Data Grid control, you have complete control over paging. If you prefer, you can enable the CustomPaging property and implement your own paging logic.