Evjen c07.tex V2 - 01/28/2008 2:01pm Page 345
Chapter 7: Data Binding in ASP.NET 3.5
If this is all the functionality you want, you probably want to create a new SqlDataSource control and
modify the
SelectCommand
so that it returns only one record, rather than returning all records as our
query does. For this example, however, you want to be able to page through all the customer data
returned by your query. To do this, simply turn on paging by setting the DetailsView’s
AllowPaging
property to
True
. You can either check the Enable Paging check box in the DetailsView smart tag or add
the attribute to the control in HTML View. Listing 7-49 shows the DetailsView code for the control.
Listing 7-49: Enabling paging on the DetailsView control
<
asp:DetailsView ID="DetailsView1" Runat="server" DataSourceID="SqlDataSource1"
AutoGenerateRows="False" DataKeyNames="CustomerID"
><
/asp:DetailsView
>
Like the GridView, the DetailsView control enables you to customize the control’s Pager using the
Pager-
Settings
-
Mode
,aswellasthe
Pager
style.
Customizing the DetailsView Display
You can customize the appearance of the DetailsView control by picking and choosing which fields the
control displays. By default, the control displays each column from the table it is working with. Much like
the GridView control, however, the DetailsView control enables you to specify that only certain selected
columns be displayed, as illustrated in Listing 7-50.
Listing 7-50: Customizing the display o f the DetailsView control
<
asp:DetailsView ID="DetailsView1" Runat="server" DataSourceID="SqlDataSource1"
AutoGenerateRows="False" DataKeyNames="CustomerID"
>
<
Fields
>
<
asp:BoundField ReadOnly="True" HeaderText="CustomerID"
DataField="CustomerID" SortExpression="CustomerID"
Visible="False" /
>
<
asp:BoundField ReadOnly="True" HeaderText="CompanyName"
DataField="CompanyName" SortExpression="CompanyName" /
>
<
asp:BoundField HeaderText="ContactName" DataField="ContactName"
SortExpression="ContactName" /
>
<
asp:BoundField HeaderText="ContactTitle" DataField="ContactTitle"
SortExpression="ContactTitle" /
>
<
/Fields
>
<
/asp:DetailsView
>
Using the DetailsView and GridView Together
This section looks at a common scenario using both the GridView and the DetailsView. In this example,
you use the GridView t o display a master view of the data and the DetailsView to show the details of
the selected GridView row. The Customers table is the data source. Listing 7-51 shows the code needed
for this.
Listing 7-51: Using the GridView and DetailsView together
<
html
>
<
head id="Head1" runat="server"
>
<
title
>
GridView & DetailsView Controls
<
/title
>
<
/head
>
Continued
345
Evjen c07.tex V2 - 01/28/2008 2:01pm Page 346
Chapter 7: Data Binding in ASP.NET 3.5
<
body
>
<
form id="form1" runat="server"
>
<
p
>
<
asp:GridView ID="GridView1" runat="server"
DataSourceId="SqlDataSource1" AllowPaging="True"
BorderColor="#DEBA84" BorderStyle="None" BorderWidth="1px"
BackColor="#DEBA84" CellSpacing="2" CellPadding="3"
DataKeyNames="CustomerID" AutoGenerateSelectButton="True"
AutoGenerateColumns="False" PageSize="5"
>
<
FooterStyle ForeColor="#8C4510"
BackColor="#F7DFB5"
><
/FooterStyle
>
<
PagerStyle ForeColor="#8C4510"
HorizontalAlign="Center"
><
/PagerStyle
>
<
HeaderStyle ForeColor="White" BackColor="#A55129"
Font-Bold="True"
><
/HeaderStyle
>
<
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
>
<
SelectedRowStyle ForeColor="White" BackColor="#738A9C"
Font-Bold="True"
><
/SelectedRowStyle
>
<
RowStyle ForeColor="#8C4510" BackColor="#FFF7E7"
><
/RowStyle
>
<
/asp:GridView
>
<
/p
>
<
p
><
b
>
Customer Details:
<
/b
><
/p
>
<
asp:DetailsView ID="DetailsView1" runat="server"
DataSourceId="SqlDataSource2"
BorderColor="#DEBA84" BorderStyle="None" BorderWidth="1px"
BackColor="#DEBA84" CellSpacing="2" CellPadding="3"
AutoGenerateRows="False" DataKeyNames="CustomerID"
>
Continued
346
Evjen c07.tex V2 - 01/28/2008 2:01pm Page 347
Chapter 7: Data Binding in ASP.NET 3.5
<
FooterStyle ForeColor="#8C4510" BackColor="#F7DFB5"
><
/FooterStyle
>
<
RowStyle ForeColor="#8C4510" BackColor="#FFF7E7"
><
/RowStyle
>
<
PagerStyle ForeColor="#8C4510" HorizontalAlign="Center"
><
/PagerStyle
>
<
Fields
>
<
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
>
<
/Fields
>
<
HeaderStyle ForeColor="White" BackColor="#A55129"
Font-Bold="True"
><
/HeaderStyle
>
<
EditRowStyle ForeColor="White" BackColor="#738A9C"
Font-Bold="True"
><
/EditRowStyle
>
<
/asp:DetailsView
>
<
asp:SqlDataSource ID="SqlDataSource1" runat="server"
SelectCommand="SELECT * FROM [Customers]"
ConnectionString="
<
%$ ConnectionStrings:AppConnectionString1 %
>
"/
>
<
asp:SqlDataSource ID="SqlDataSource2" runat="server"
SelectCommand="SELECT * FROM [Customers]"
FilterExpression="CustomerID=’{0}’"
ConnectionString="
<
%$ ConnectionStrings:AppConnectionString1 %
>
"
>
<
FilterParameters
>
<
asp:ControlParameter Name="CustomerID" ControlId="GridView1"
PropertyName="SelectedValue"
><
/asp:ControlParameter
>
<
/FilterParameters
>
<
/asp:SqlDataSource
>
<
/form
>
<
/body
>
<
/html
>
When this code is run in your browser, you get the results shown in Figure 7-28.
In this figure, one of the rows in the GridView has been selected (noticeable because of the gray
highlighting). The details of the selected row are shown in the DetailsView control directly below the
GridView control.
347
Evjen c07.tex V2 - 01/28/2008 2:01pm Page 348
Chapter 7: Data Binding in ASP.NET 3.5
Figure 7-28
To see how this works, look at the changes that were made to the second SqlDataSource control, Sql-
DataSource2. Notice that a
FilterExpression
attribute has been added, which is used to filter the data
reterived by the
SelectCommand
.
Thevaluegiventothe
FilterExpression
attribute expresses how you want the SqlDataSource control
to filter its
Select
command. In this case, the value of the
FilterExpression
is
CustomerID=‘0’
.This
tells the SqlDataSource control to filter records that it returns by the CustomerID given to it, as shown in
Listing 7-52. The
FilterExpression
attribute uses the same syntax as
String.Format.
Listing 7-52: Filtering SqlDataSource data with a FilterExpression
<
asp:SqlDataSource ID="SqlDataSource2" runat="server"
SelectCommand="SELECT * FROM [Customers]"
FilterExpression="CustomerID=’{0}’"
ConnectionString="
<
%$ ConnectionStrings:AppConnectionString1 %
>
"
>
<
FilterParameters
>
<
asp:ControlParameter Name="CustomerID" ControlId="GridView1"
348
Evjen c07.tex V2 - 01/28/2008 2:01pm Page 349
Chapter 7: Data Binding in ASP.NET 3.5
PropertyName="SelectedValue"
><
/asp:ControlParameter
>
<
/FilterParameters
>
<
/asp:SqlDataSource
>
The parameter specified in the
FilterExpression
attribute,
CustomerID
, is defined within the
SqlDataSource control through the use of the
<
FilterParameters
> element. This sample uses an
<
asp:ControlParameter
> to specify the name of the parameter, the control that the parameter value
is coming from (the GridView control), and the property name that is used to populate the parameter
value.
Finally, be sure to include the
DataKeyNames
attribute in the GridView control. In this case supply
CustomerID
as the value. This tells the GridView which column(s) are to be used as a primary key.
When a user selects a row, the value of that column is then provided to the DetailsView control via the
SelectValue
property. The procedure for adding the
DataKeyNames
attribute to the GridView is shown
in Listing 7-53.
Listing 7-53: Adding the DataKeyNames attribute to the GridView
<
asp:GridView ID="GridView1" runat="server"
DataSourceId="SqlDataSource1" AllowPaging="True"
BorderColor="#DEBA84" BorderStyle="None" BorderWidth="1px"
BackColor="#DEBA84" CellSpacing="2" CellPadding="3"
DataKeyNames="CustomerID" AutoGenerateSelectButton="True"
AutoGenerateColumns="False" PageSize="5"
>
SelectParameters versus FilterParameters
You might have noticed in the previous example that the
FilterParameters
seem to provide the same
functionality as the
SelectParameters
. Although both produce essentially the same result, they use very
different methods. As you saw in the section ‘‘Filtering Data Using SelectParameters,’’ using the
Select-
Parameters
allows the developer to inject values into a
WHERE
clause specified in the
SelectCommand
.This
limits the rows that are returned from the SQL Server and held in memory by the data source control.
The advantage is that by limiting the amount of data returned from SQL, you can make your applica-
tion faster and reduce the amount of memory it consumes. The disadvantage is that you are confined to
working with the limited subset of data returned by the SQL query.
FilterParameters
, on the other hand, do not need to use a
WHERE
clause in the
SelectCommand
,requiring
all the data to be returned from the SQL server to the Web server. The filter is applied to the data source
control’s in-memory data, rather than using a
WHERE
clause, which would have allowed SQL Server to
limit the results it returns. The disadvantage of the filter method is that more data has to be transferred
to the Web server. However, in some cases this is an advantage such as when you are performing many
filters of one large chunk of data (for instance, to enable paging in the DetailView), you do not have to
call out to SQL Server each time you need the next record. All the data is stored in cache memory by the
data source control.
Inserting, Updating, and Deleting Data Using DetailsView
Inserting data using the DetailsView is similar to all the other data functions that you have performed. To
insert data using the DetailsView, simply add the
AutoGenerateInsertButton
attribute to the
DetailsView control as shown in Listing 7-54.
349
Evjen c07.tex V2 - 01/28/2008 2:01pm Page 350
Chapter 7: Data Binding in ASP.NET 3.5
Listing 7-54: Adding an AutoGenerateInsertButton attribute to the DetailsView
<
asp:DetailsView ID="DetailsView1" runat="server"
DataSourceId="SqlDataSource2"
AutoGenerateRows="False" AutoGenerateInsertButton="true"
DataKeyNames="CustomerID"
>
Then add the
InsertCommand
and corresponding
InsertParameter
elements to the SqlDataSource con-
trol, as shown in Listing 7-55.
Listing 7-55: Adding an InsertCommand to the SqlDataSource control
<
asp:SqlDataSource ID="sqlDataSource2" runat="server"
SelectCommand="SELECT * FROM [Customers]"
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)" DeleteCommand="DELETE FROM [Customers] WHERE
[CustomerID] = @original_CustomerID"
ConnectionString="
<
%$ ConnectionStrings:AppConnectionString1 %
>
"
>
<
InsertParameters
>
<
asp:Parameter Type="String" Name="CustomerID"
><
/asp:Parameter
>
<
asp:Parameter Type="String" Name="CompanyName"
><
/asp:Parameter
>
<
asp:Parameter Type="String" Name="ContactName"
><
/asp:Parameter
>
<
asp:Parameter Type="String" Name="ContactTitle"
><
/asp:Parameter
>
<
asp:Parameter Type="String" Name="Address"
><
/asp:Parameter
>
<
asp:Parameter Type="String" Name="City"
><
/asp:Parameter
>
<
asp:Parameter Type="String" Name="Region"
><
/asp:Parameter
>
<
asp:Parameter Type="String" Name="PostalCode"
><
/asp:Parameter
>
<
asp:Parameter Type="String" Name="Country"
><
/asp:Parameter
>
<
asp:Parameter Type="String" Name="Phone"
><
/asp:Parameter
>
<
asp:Parameter Type="String" Name="Fax"
><
/asp:Parameter
>
<
/InsertParameters
>
<
/asp:SqlDataSource
>
Figure 7-29 shows the DetailsView control page loaded in the browser in insert mode, ready to add a
new record.
Figure 7-30 shows the DetailsView control after a new record has been inserted.
Updating and deleting data using the DetailsView control are similar to updating and deleting data from
the GridView. Simply specify the
UpdateCommand
or
DeleteCommand
attributes in the DetailView control;
then provide the proper
UpdateParameters
and
DeleteParameters
elements.
ListView
ASP.NET 3.5 introduces a new data-bound list control called the ListView. The idea behind the ListView
control is to offer a data-bound control that bridges the gap between the highly structured GridView
control introduced in ASP.NET 2.0, and the anything goes, unstructured controls DataList and Repeater.
350
Evjen c07.tex V2 - 01/28/2008 2:01pm Page 351
Chapter 7: Data Binding in ASP.NET 3.5
Figure 7-29
Figure 7-30
351
Evjen c07.tex V2 - 01/28/2008 2:01pm Page 352
Chapter 7: Data Binding in ASP.NET 3.5
In the p ast, many developers who wanted a grid style data control chose the GridView because it was
easy to use a nd offered powerful features such as data editing, paging, and sorting. Unfortunately, the
more developers dug into the control, the more they found that controlling the way it rendered its HTML
output was exceedingly difficult. This was problematic if you wanted to lighten the amount of markup
generated by the control, or use CSS exclusively to control the control’s layout and style.
On the other side of the coin, many developers were drawn the DataList or Repeater because of the
enhanced control t hey got over rendering. These controls contained little to no notion of layout and
required the developer to start from scratch in laying out their data. Unfortunately, these controls lacked
some of the basic features of the GridView, such as paging and sorting, or in the case of the Repeater, any
notion of data editing.
This is where the ListView attempts to fill the gap between these controls. The control itself emits no
runtime generated HTML markup; instead it relies on a series of 11 different control templates that
represent the different areas of the control and the possible states of those areas. Within these templates
you can place markup auto-generated by the control at design-time, o r markup created by the developer,
but in either case the developer retains complete co ntrol over not only the markup for individual data
items in the control, but of the markup for the layout of the entire control. Additionally, because the
control readily understands and handles data editing and paging, you can let the control do much of the
data management work, allowing you to focus primarily on the display of your data.
Getting Started with the ListView
To get started using the ListView, simply drop the control on the design surface and assign a data source
to it just as you would any other data-bound list control. Once you assign the data source, however,
you will see that there is no design-time layout preview available as you might expect. This is because,
by default, the ListView has no layout defined and it is completely up to you to define the control’s
layout. In fact, the design-time rendering of the control e ven tells you that you need to define at least an
ItemTemplate and LayoutTemplate in order to use the control. The LayoutTemplate serves as the root
template for the control, and the ItemTemplate serves as the template for each individual data item in
the control.
You have two options for defining the templates needed by the ListView. You can either edit the tem-
plates directly by changing the Current View option in the ListView smart tag, or you can select a
predefined layout from the controls smart tag. Changing Current View allows you to see a runtime view
of each of the available templates, and edit t he contents of those templates directly just as you would nor-
mally edit any other control template. Figure 7-31 shows the Current View drop-down in the ListView’s
smart tag.
The second option and probably the e asier to start with, is to choose a predefined layout template
from the Configure ListView dialog. To open this dialog, simply click the ConfigureListView option from
the smart tag. Once open, you are presented with a dialog that lets you select between several different
pre-defined layouts, select different style options, and even configure basic behavior options such as
editing and paging. This dialog is shown in Figure 7-32.
The control includes five dif ferent layout types: Grid, Tiled, Bulleted List, Flow, and Single Row and four
different style options. A preview of each type is presented in the dialog, and as you change the currently
selected layout and style, the preview is updated.
352
Evjen c07.tex V2 - 01/28/2008 2:01pm Page 353
Chapter 7: Data Binding in ASP.NET 3.5
Figure 7-31
Figure 7-32
353
Evjen c07.tex V2 - 01/28/2008 2:01pm Page 354
Chapter 7: Data Binding in ASP.NET 3.5
To see exactly how the control defines each layout option, select the Grid layout with the Colorful
style and enable Inserting, Editing, Deleting, and Paging. Click OK to apply your choices and close the
dialog box. When the dialog box closes, you should now see that you get a design-time preview
of your layout and running the page results in the ListView generating a grid layout, as shown
in Figure 7-33.
Figure 7-33
ListView Templates
Once you have a pplied a layout template to the ListView, if you look at the Source window in Visual
Studio you can see that in order to provide the layout, the control actually generated a significant
chunk of markup. This markup is generated based on the layout that you chose in the Configure
ListView dialog.
If you closely examine t he markup that has been generated for the Grid layout used in the previous
section, you will see that, by default, the control creates markup for seven different control templates: the
ItemTemplate, AlternatingItemTemplate, SelectedItemTemplate, InsertItemTemplate, EditItemTemplate,
EmptyDataTemplate, and LayoutTemplate. These are just some of the 11 different templates t hat the
control exposes, and that you can use to provide markup for the different states of the control. Choosing
a different predefined layout option results in the control generating a different collection of templates.
Of course, you can also always manually add or remove any of the templates yourself. All 11 templates
are listed in the following table.
354