9.3. GridView ControlNow that you have a working data source control on your web page, let's hook it up to a control to display the data you've retrieved. You will use a GridView control, the workhorse data grid in ASP.NET. The GridView is derived from the BaseDataBoundControl class, along with many other controls, such as the AdRotator , DetailsView , and FormView controls, the members of the ListControl class, such as CheckBoxList , RadioButtonList , and so on, and composite controls, such as the password controls, wizards, and so on. The DataGrid and DataList controls derive from BaseDataList , not BaseDataBoundControl . (Refer to Figure 3-3 in Chapter 3 for a schematic diagram of the class structure of System.Web.UI.Control .) Though they derive from different base classes, the GridView and the DataList (described later in this chapter) share many of the same properties.
Many of the most commonly used properties of the GridView control not inherited from the control or WebControl classes are listed in Table 9-1. Many of these properties are described and used in subsequent sections of this chapter. Table 9-1. GridView properties not inherited from WebControl
Drag a GridView onto the page. The GridView recognizes a SqlDataSource is on the page and does not create its own. Click on the GridView 's smart tag and choose your Data Source, as shown in Figure 9-6. Figure 9-6. Choosing an existing Data SourceAs soon as you set the data source, the data grid is redrawn, with a column for each field returned by the data source. The column headers have been filled in for you. Open the smart tag again and click on Paging (which will allow the grid to show a limited number of entries on each page and will make the display easier to view). Switch to Source view, and examine the declaration of the GridView , as shown in Example 9-1. Example 9-1. GridView control bound to data source <asp:GridView ID="GridView1" runat="server" PageSize="4" DataSourceID="SqlDataSource1" AutoGenerateColumns="False" DataKeyNames="CustomerID"> <Columns> <asp:BoundField ReadOnly="True" HeaderText="CustomerID" DataField="CustomerID" SortExpression="CustomerID"> </asp:BoundField> <asp:BoundField HeaderText="CompanyName" DataField="CompanyName" SortExpression="CompanyName"> </asp:BoundField> <asp:BoundField HeaderText="ContactName" DataField="ContactName" SortExpression="ContactName"> </asp:BoundField> <asp:BoundField HeaderText="ContactTitle" DataField="ContactTitle" SortExpression="ContactTitle"> </asp:BoundField> <asp:BoundField HeaderText="Address" DataField="Address" SortExpression="Address"> </asp:BoundField> <asp:BoundField HeaderText="City" DataField="City" SortExpression="City"> </asp:BoundField> <asp:BoundField HeaderText="Region" DataField="Region" SortExpression="Region"> </asp:BoundField> <asp:BoundField HeaderText="PostalCode" DataField="PostalCode" SortExpression="PostalCode"> </asp:BoundField> <asp:BoundField HeaderText="Country" DataField="Country" SortExpression="Country"> </asp:BoundField> <asp:BoundField HeaderText="Phone" DataField="Phone" SortExpression="Phone"> </asp:BoundField> <asp:BoundField HeaderText="Fax" DataField="Fax" SortExpression="Fax"> </asp:BoundField> </Columns> </asp:GridView> VS2005 has done a lot of work for you. It has examined the data source and created a BoundField for each column in the data. Further, it has set the HeaderText to the name of the DataField . Finally, you'll notice on the declaration of the GridView that it has set AutoGenerateColumns to False (highlighted in Example 9-1). If you were creating the GridView by hand, and if you were going to let the grid create all the columns right from the retrieved data, you could simplify the code by setting AutoGenerateColumns to TRue . To see this at work, create a second GridView in the Source view of the content file below the one you just created using drag and drop. <asp:GridView ID="GridView2" runat="server" AllowPaging="true"PageSize="4" DataSourceID="SqlDataSource1" AutoGenerateColumns="True" DataKeyNames="CustomerID"/> Run the application. You should see two data grids, one above the other, as shown in Figure 9-7. Figure 9-7. Creating two gridsone by handThey are indistinguishable. So why does VS2005 create the more complex version? By turning off AutoGenerate Column VS2005 gives you much greater control over the presentation of your data. You can, for example, set the headings on the columns (such as changing ContactTitle to Title). You can remove columns you don't need, and you can add new columns with controls for manipulating the rows. You can make these changes by hand-coding the HTML in the Source view or by clicking on the smart tag for the GridView and choosing Edit Columns. Doing so brings up the Fields dialog box, as shown in Figure 9-8. Figure 9-8. Fields dialog boxThe dialog box is divided into three main areas: the list of available fields, the list of selected fields (with arrows to remove fields or reorder the list), and the Bound Field Properties window on the right. Click on a selected field (such as ContactTitle ), and you can set the way that field will be displayed in the data grid (such as changing the header to Title). While you're examining what you can do with the GridView , let's make it look nicer. First, delete (or comment out) the second (simpler) grid. Second, open the smart tag on the first grid. Click on AutoFormat and choose one of the formatting options. (You can, of course format it by hand, but why work so hard?) I'll choose "Brown Sugar" because it shows up well in the printed book. While you're at it, click on Enable Sorting (Presto! The columns can be sorted). Run the application. You'll see the output in Figure 9-9. Figure 9-9. Running the formatted grid9.3.1. Adding Insert, Update, and Delete StatementsThe SqlDataSource that you've created currently has only a select statement to extract data from the database: <asp:SqlDataSource ID="SqlDataSource1" runat="server" SelectCommand="SELECT * FROM [Customers]" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"> </asp:SqlDataSource> You can, however, ask your data source control to create the remaining C reate, R etrieve, U pdate and D elete (CRUD ) statements using a wizard to make your work easier. To do so, switch to Design view, click on the SqlDataSource 's smart tag, and choose Configure Data Source....The Configure Data Source wizard opens, displaying your current connection string. Click Next and the Configure Select Statement dialog box is displayed. Click the Advanced button. This opens the Advanced SQL Generation Options dialog box. Click the Generate Insert, Update, and Delete statements checkbox, as shown in Figure 9-10. Figure 9-10. Add the CRUD methodsClicking this checkbox instructs the wizard to create the remaining CRUD methods, and it enables the second checkbox: Use optimistic concurrency. Do not check this yet. Click OK, Next, and then Finish. You will be asked to update your grid, which unfortunately will wipe out all your customization, but the good news is that you are now bound to a data source control that provides all four CRUD methods. Open the smart tag, add back the look and feel you want, and check Enable Editing and Enable Deleting. Take a look at the HTML generated for the SqlDataSource control, as shown in Example 9-2. Example 9-2. Source code for SQL with CRUD<asp:SqlDataSource ID="SqlDataSource1" runat="server" SelectCommand="SELECT * FROM [Customers]" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" DeleteCommand="DELETE FROM [Customers] WHERE [CustomerID] = @original_CustomerID" InsertCommand="INSERT INTO [Customers] ([CustomerID], [CompanyName], [ContactName], [ContactTitle], [Address], [City], [Region], [PostalCode], [Country], [Phone], [Fax]) VALUES (@CustomerID, @CompanyName, @ContactName, @ContactTitle, @Address, @City, @Region, @PostalCode, @Country, @Phone, @Fax)" UpdateCommand="UPDATE [Customers] SET [CompanyName] = @CompanyName, [ContactName] = @ContactName, [ContactTitle] = @ContactTitle, [Address] = @Address, [City] = @City, [Region] = @Region, [PostalCode] = @PostalCode, [Country] = @Country, [Phone] = @Phone, [Fax] = @Fax WHERE [CustomerID] = @original_CustomerID"> <DeleteParameters> <asp:Parameter Type="String" Name="original_CustomerID" /> </DeleteParameters> <UpdateParameters> <asp:Parameter Type="String" Name="CompanyName" /> <asp:Parameter Type="String" Name="ContactName" /> <asp:Parameter Type="String" Name="ContactTitle" /> <asp:Parameter Type="String" Name="Address" /> <asp:Parameter Type="String" Name="City" /> <asp:Parameter Type="String" Name="Region" /> <asp:Parameter Type="String" Name="PostalCode" /> <asp:Parameter Type="String" Name="Country" /> <asp:Parameter Type="String" Name="Phone" /> <asp:Parameter Type="String" Name="Fax" /> <asp:Parameter Type="String" Name="original_CustomerID" /> </UpdateParameters> <InsertParameters> <asp:Parameter Type="String" Name="CustomerID" /> <asp:Parameter Type="String" Name="CompanyName" /> <asp:Parameter Type="String" Name="ContactName" /> <asp:Parameter Type="String" Name="ContactTitle" /> <asp:Parameter Type="String" Name="Address" /> <asp:Parameter Type="String" Name="City" /> <asp:Parameter Type="String" Name="Region" /> <asp:Parameter Type="String" Name="PostalCode" /> <asp:Parameter Type="String" Name="Country" /> <asp:Parameter Type="String" Name="Phone" /> <asp:Parameter Type="String" Name="Fax" /> </InsertParameters> </asp:SqlDataSource> Taking this apart, you see first the declaration for the SqlDataSource (and the closing tag at the bottom). After the ID and the obligatory runat="server" , you see four attributes: the SelectCommand (which was there previously) and the new DeleteCommand , InsertCommand , and UpdateCommand . SelectCommand ="SELECT * FROM [Customers]" DeleteCommand ="DELETE FROM [Customers] WHERE [CustomerID] = @original_CustomerID" InsertCommand ="INSERT INTO [Customers] ([CustomerID], [CompanyName], [ContactName], [ContactTitle], [Address], [City], [Region], [PostalCode], [Country], [Phone], [Fax]) VALUES (@CustomerID, @CompanyName, @ContactName, @ContactTitle, @Address, @City, @Region, @PostalCode, @Country, @Phone, @Fax)" UpdateCommand ="UPDATE [Customers] SET [CompanyName] = @CompanyName, [ContactName] = @ContactName, [ContactTitle] = @ContactTitle, [Address] = @Address, [City] = @City, [Region] = @Region, [PostalCode] = @PostalCode, [Country] = @Country, [Phone] = @Phone, [Fax] = @Fax WHERE [CustomerID] = @original_CustomerID"> The DeleteCommand takes a single parameter ( @original_CustomerID ), specified in the DeleteParameters element. <DeleteParameters> <asp:Parameter Type="String" Name="original_CustomerID" /> </DeleteParameters> The UpdateCommand requires more parameters, one for each column you'll be updating, as well as a parameter for the original CustomerID (to make sure the correct record is updated). Similarly, the InsertCommand takes parameters for each column for the new record. All of these parameters are within the definition of the SqlDataSource . |