Download File - Chandresh Gamdha

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Intelligent maintenance system wikipedia , lookup

Transcript
Ch6: Binding Data to Web Controls (6.1) Overview of Data Binding (6.2) Building a Server Control to a Data Source (6.3) Creating Master/Detail Forms (6.4) Data Binding without Data Binding Expressions Overview of Data Binding Data binding refers to the process of dynamically assigning a value to a property of a control at runtime. For example, you can use data binding to bind the properties of a control to a data source such as the contents of a SQL Server database table. Remember, the topic of data binding is not limited to working with database data. You can bind the properties of a control to expressions, properties, methods, collections, or even the properties of another control. The distinctive aspect of data binding is not the data part, but the binding part. Data binding enables you to control exactly when a value is bound to a property. The best way to get an idea of how data binding works is to look at some examples. <Script Runat="Server"> Sub Page_Load lblMessage.DataBind() End Sub Function GetTime() As String Return DateTime.Now.ToString( "T" ) End Function </Script> <html> <head><title>SimpleBind.aspx</title></head> <body> <form Runat="Server"> <asp:Label ID="lblMessage" Text='<%# GetTime() %>' Runat="Server" /> </form> </body> </html> The special <%# and %> tags delimit the data binding expression. In this case, the value of the data binding expression is the value of the GetTime() function. You wrap the value of a data binding expression with apostrophe characters rather than the usual quotation marks. Getting in the habit of always using apostrophes is a good idea because quotation marks can cause errors. Using quotation marks generates an error when the data binding expression itself contains quotation marks. The DataBind() method is called on the Label control named lblMessage. When the DataBind() method is called, the value of the GetTime() function is assigned to the Text property of the Label control. The important feature of data binding is that you can control when a data binding expression is evaluated. If the DataBind() method is never called in the page, the lblMessage Text property is never assigned a value. Every control has a DataBind() method. It is a method of the base Control class used by both the Web and HTML controls. When you call the DataBind() method on a control, all the data binding expressions associated with that control are evaluated. Data binding occurs for both the control itself and all the child controls of the control. Remember that an ASP.NET page is also a control. If you call DataBind() without specifying a control, the Page control's DataBind() method is called, and all the data binding expressions in the page are evaluated. <Script Runat="Server">
Sub Page_Load
DataBind()
End Sub
Function GetTime() As String
Return DateTime.Now.ToString( "T" )
End Function
</Script>
<html>
<head><title>SimplePageDataBind.aspx</title></head>
<body>
<form Runat="Server">
<asp:Label
ID="lblMessage1"
Text='<%# GetTime() %>'
Runat="Server" />
<p>
<asp:Label
ID="lblMessage2"
Text='<%# GetTime() %>'
Runat="Server" />
</form>
</body>
</html>
This example demonstrates how databind actually works. <Script Runat="Server">
Dim intNextNum As Integer
Sub Page_Load
lblMessage2.DataBind()
lblMessage1.DataBind()
End Sub
Function GetNext() As String
intNextNum += 1
Return intNextNum
End Function
</Script>
<html>
<head><title>DataBindTest1.aspx</title></head>
<body>
<form Runat="Server">
<asp:Label
ID="lblMessage1"
Text='<%# getNext %>'
Runat="Server" />
<p>
<asp:Label
ID="lblMessage2"
Text='<%# getNext %>'
Runat="Server" />
</form>
</body>
</html>
This example demonstrates difference between page wise data bind and block wise data bind. <Script Runat="Server">
Dim intNextNum As Integer
Sub Page_Load
lblMessage1.DataBind()
lblMessage2.DataBind()
DataBind()
End Sub
Function GetNext() As String
intNextNum += 1
Return intNextNum
End Function
</Script>
<html>
<head><title>DataBindTest2.aspx</title></head>
<body>
<form Runat="Server">
<asp:Label
ID="lblMessage1"
Text='<%# GetNext() %>'
Runat="Server" />
<p>
<asp:Label
ID="lblMessage2"
Text='<%# GetNext() %>'
Runat="Server" />
</form>
</body>
</html>
When the first DataBind() method is called, the first Label control is assigned the value 1. When the second DataBind() method is called, the second Label control is assigned the value 2. Here's the interesting part: When the DataBind() method is called a third time, data binding occurs for all the controls on the page all over again. So, when all is said and done and the page is displayed, the first Label control displays the value 3, and the second Label control displays the value 4 Binding a Server Control to a Data Source In the following sections, you learn how to use data binding with several ASP.NET controls, such as the Repeater, DropDownList, RadioButtonList, and ListBox controls. You learn how to use the DataSource property to bind the items from a data source such as a database table or an ArrayList to a control. You also learn how to use templates to format how the data is displayed. Binding to the Repeater Control The Repeater control does not display anything unless it is bound to a data source. Typically, you use the Repeater control to display the records from a database table, although you can also bind the control to other data sources such as collections. Imagine that you have a database table named Authors and you want to display all the rows from this database table within an ASP.NET page. <%@ Import Namespace="System.Data.SqlClient" %>
<Script Runat="Server">
Sub Page_Load
Dim conPubs As SqlConnection
Dim cmdSelect As SqlCommand
Dim dtrAuthors As SqlDataReader
' Retrieve records from database
conPubs = New SqlConnection(
"Server=localhost;UID=sa;PWD=secret;Database=Pubs" )
cmdSelect = New SqlCommand( "Select * From Authors", conPubs )
conPubs.Open()
dtrAuthors = cmdSelect.ExecuteReader()
' Bind to Repeater
rptAuthors.DataSource = dtrAuthors
rptAuthors.DataBind()
dtrAuthors.Close()
conPubs.Close()
End Sub
</Script>
<html>
<head><title>Repeater.aspx</title></head>
<body>
<form Runat="Server">
<asp:Repeater
ID="rptAuthors"
Runat="Server">
<ItemTemplate>
<%# Container.DataItem( "au_lname" ) %>
</ItemTemplate>
</asp:Repeater>
</form>
</body>
</html>
All the work in above example is accomplished within the Page_Load subroutine. This subroutine opens a connection to a Microsoft SQL Server database and retrieves all the records from the Authors database table into a SqlDataReader. Next, the SqlDataReader is assigned to the DataSource property of the Repeater control. Finally, the DataBind() method is called, and the items from the SqlDataReader are bound to the Repeater control. The Repeater control is declared with the following tags: <asp:Repeater ID="dtrAuthors" Runat="Server"> <ItemTemplate> <%# Container.DataItem( "au_lname" ) %> </ItemTemplate> </asp:Repeater> The au_lname column for each of the records retrieved from the Authors table is displayed by the Repeater control. The following data binding expression represents the au_lname column: <%# Container.DataItem( "au_lname" ) %> Notice that this expression uses the data binding tags <%# and %>. This expression does not have a value until the Repeater control's DataBind() method is called. Using Templates If you look closely at the ASP.NET page in above example, you notice that the Repeater control uses a tag named <ItemTemplate>. The ItemTemplate is one example of a template. The Repeater control uses templates to control formatting. Templates enable you to apply complicated formatting to each of the items displayed by a control. You can place any HTML tags that you please within a template. A template can also contain other controls and even inline ASP.NET code. The Repeater control actually supports five types of templates: •
HeaderTemplate— Controls how the header of the Repeater control is formatted •
ItemTemplate— Controls the formatting of each item displayed by the Repeater control •
AlternatingItemTemplate— Controls how alternate items are formatted •
SeparatorTemplate— Displays a separator between each item displayed by the Repeater control •
FooterTemplate— Controls how the footer of the Repeater control is formatted Now, imagine that you want every other item displayed by the Repeater control to have a purple and italic font, and you want a horizontal rule to separate the items <asp:Repeater
ID="rptAuthors"
Runat="Server">
<ItemTemplate>
<%# Container.DataItem( "au_lname" ) %>
</ItemTemplate>
<AlternatingItemTemplate>
<font color="purple"><i>
<%# Container.DataItem( "au_lname" ) %>
</i></font>
</AlternatingItemTemplate>
<SeparatorTemplate>
<hr>
</SeparatorTemplate>
</asp:Repeater>
You can also use templates with a repeater control to format the items displayed by the control in an html table. i.e. <%@ Import Namespace="System.Data.SqlClient" %>
<Script Runat="Server">
Sub Page_Load
Dim conPubs As SqlConnection
Dim cmdSelect As SqlCommand
Dim dtrAuthors As SqlDataReader
' Retrieve records from database
conPubs = New SqlConnection(
"Server=localhost;UID=sa;PWD=secret;Database=Pubs" )
cmdSelect = New SqlCommand( "Select * From Authors", conPubs )
conPubs.Open()
dtrAuthors = cmdSelect.ExecuteReader()
' Bind to Repeater
rptAuthors.DataSource = dtrAuthors
rptAuthors.DataBind()
dtrAuthors.Close()
conPubs.Close()
End Sub
</Script>
<html>
<head><title>RepeaterTable.aspx</title></head>
<body>
<form Runat="Server">
<asp:Repeater
ID="rptAuthors"
Runat="Server">
<HeaderTemplate>
<table border=1 cellpadding=4>
<tr bgcolor="#eeeeee">
<th>First Name</th>
<th>Last Name</th>
<th>Phone</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%# Container.DataItem( "au_fname" ) %></td>
<td><%# Container.DataItem( "au_lname" ) %></td>
<td><%# Container.DataItem( "phone" ) %></td>
</tr>
</ItemTemplate>
<AlternatingItemTemplate>
<tr bgcolor="lightyellow">
<td><%# Container.DataItem( "au_fname" ) %></td>
<td><%# Container.DataItem( "au_lname" ) %></td>
<td><%# Container.DataItem( "phone" ) %></td>
</tr>
</AlternatingItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</form>
</body>
</html>
View State and the Repeater Control The Repeater control, like other server controls, participates in a page's view state. By default,
this means that every time you create a Repeater control on a page, all the information for each
item in the control is copied into the hidden VIEWSTATE form field.
Typically, you use the Repeater control simply to display a list of items, and you are not
interested in preserving its view state across multiple page submissions. Because preserving a
Repeater control's view state can slow down the rendering of a page, it is wise to disable view
state for this control when you don't need it.
To disable view state for an individual control, set the EnableViewState property to the value
False like this:
<asp:Repeater
ID="rptAuthors"
EnableViewState="False"
Runat="Server">
Binding to the DropDownList Control Binding data to a DropDownList control is similar to binding data to a Repeater control. The general technique is to assign a data source to the DropDownList control's DataSource property and call the DataBind() method. You must set one additional property with the DropDownList control. You must set its DataTextField property to indicate the column that you want to bind to the control. The DropDownList control has a DataValueField property. You need to set this property when you want different Value and Text properties associated with each item in a DropDownList control. Example: <%@ Import Namespace="System.Data.SqlClient" %> <Script Runat="Server"> Sub Page_Load If Not IsPostBack Then Dim conPubs As SqlConnection Dim cmdSelect As SqlCommand Dim dtrAuthors As SqlDataReader conPubs = New SqlConnection( "Server=localhost;UID=sa;PWD=secret;Database=Pubs" ) conPubs.Open() cmdSelect = New SqlCommand( "Select au_lname From Authors", conPubs ) dtrAuthors = cmdSelect.ExecuteReader() dropAuthors.DataSource = dtrAuthors dropAuthors.DataTextField = "au_lname" dropAuthors.DataBind() dtrAuthors.Close() conPubs.Close() End If End Sub </Script> <html> <head><title>DropDownList.aspx</title></head> <body> <form Runat="Server"> <asp:DropDownList ID="dropAuthors" Runat="Server" /> <asp:Button Text="Pick Author!" Runat="Server" /> </form> </body> </html> One thing you should notice about the Page_Load subroutine is that it uses the IsPostBack
property to check whether the page has already been submitted. The database records are
retrieved and bound to the DropDownList control when the page is first opened, but not
thereafter.
The list of author last names is preserved in the page's view state when the page is posted back to
the server. You need to retrieve the records from the database only the first time the page is
opened, and the records will be preserved in the page's hidden __VIEWSTATE form field.
Neglecting to check the IsPostBack property produces two bad results. First, it hurts the
performance of the page because the records need to be retrieved from the database every time
the page is opened. Retrieving records from a database is a resource-intensive task.
Second, if a user selects an author from the DropDownList control, and you rebind the
DropDownList to the database table, the user's selection is lost. Binding a DropDownList resets
the SelectedIndex and SelectedItem properties of the control.
Binding to the RadioButtonList Control You can bind a RadioButtonList control to a data source by setting its DataSource and
DataTextField properties and calling its DataBind() method.
Example : <%@ Import Namespace="System.Data.SqlClient" %> <Script Runat="Server"> Sub Page_Load If Not IsPostBack Then Dim conNorthwind As SqlConnection Dim cmdSelect As SqlCommand Dim dtrCategories As SqlDataReader conNorthwind = New SqlConnection( "Server=localhost;UID=sa;PWD=secret;Database=Northwind" ) cmdSelect = New SqlCommand( "Select CategoryName From Categories", conNorthwind ) conNorthwind.Open() dtrCategories = cmdSelect.ExecuteReader() radlCategories.DataSource = dtrCategories radlCategories.DataTextField = "CategoryName" radlCategories.DataBind() dtrCategories.Close() conNorthwind.Close() End If End Sub </Script> <html> <head><title>RadioButtonList.aspx</title></head> <body> <form Runat="Server"> <asp:RadioButtonList ID="radlCategories" Runat="Server" /> <p> <asp:Button Text="Select A Category!" Runat="Server" /> </form> </body> </html> Remember to use the IsPostBack property to bind the RadioButtonList to the DataReader
only when the page is opened the first time. If you neglect to do so, the selected radio button is
lost every time the page is submitted.
The RadioButtonList control has a DataValueField property. You need to set this property when you want different Value and Text properties associated with each item in a RadioButtonList control. Binding to the CheckBoxList Control You can bind a data source, such as a database table, to a CheckBoxList control by setting the
control's DataSource and DataTextField properties and calling its DataBind() method.
<%@ Import Namespace="System.Data.SqlClient" %> <Script Runat="Server"> Sub Page_Load If Not IsPostBack Then Dim conPubs As SqlConnection Dim cmdSelect As SqlCommand Dim dtrTitles As SqlDataReader conPubs = New SqlConnection( "Server=localhost;UID=sa;PWD=secret;Database=Pubs" ) cmdSelect = New SqlCommand( "Select Title From Titles", conPubs ) conPubs.Open() dtrTitles = cmdSelect.ExecuteReader() chklTitles.DataSource = dtrTitles chklTitles.DataTextField = "Title" chklTitles.DataBind() dtrTitles.Close() conPubs.Close() End If End Sub </Script> <html> <head><title>CheckBoxList.aspx</title></head> <body> <form Runat="Server"> <asp:CheckBoxList ID="chklTitles" Runat="Server" /> <p> <asp:Button Text="Select A Title!" Runat="Server" /> </form> </body> </html> Creating Master/Detail Forms The following sections describe an advanced application of data binding. Two methods of
creating master/detail forms are discussed. You learn how to create both single-page and
multipage master/detail forms.
What's a master/detail form? Imagine that you have two database tables named Products and
Categories. Each product in the Products table is associated with a category in the Categories
table. Now, suppose that you want the users of your Web site to be able to view different lists of
products by selecting different categories. In this case, you need to build a master/detail form.
Or, imagine that you have a database table named Authors. For each author, you have such
information as the author's first and last name, phone number, and so on. Suppose that you want
to be able to select from a list of author last names and view details on a particular author. This is
another situation in which you need to build a master/detail form.
One approach to building master/detail forms is to place both the master and detail information
on the same page. For example, the page in ex1 contains a DropDownList control that represents
product categories and a Repeater control that represents a list of products. When you select a
product category, the corresponding products are displayed.
Ex1 <%@ Import Namespace="System.Data.SqlClient" %> <Script Runat="Server"> Sub Page_Load If Not IsPostBack Then Dim conNorthwind As SqlConnection Dim cmdSelect As SqlCommand Dim dtrCategories As SqlDataReader conNorthwind = New SqlConnection( "Server=localhost;UID=sa;PWD=secret;Database=Northwind" ) cmdSelect = New SqlCommand( "Select CategoryID, CategoryName From Categories", conNorthwind ) conNorthwind.Open() dtrCategories = cmdSelect.ExecuteReader() dropCategories.DataSource = dtrCategories dropCategories.DataTextField = "CategoryName" dropCategories.DataValueField = "CategoryID" dropCategories.DataBind() dropCategories.Items.Insert( 0, New ListItem( "none selected", ‐1 ) ) dtrCategories.Close() conNorthwind.Close() End If End Sub Sub BindProducts( intCatID As Integer ) Dim conNorthwind As SqlConnection Dim cmdSelect As SqlCommand Dim strSelect As String Dim dtrProducts As SqlDataReader conNorthwind = New SqlConnection( "Server=localhost;UID=sa;PWD=secret;Database=Northwind" ) conNorthwind.Open() strSelect = "Select ProductName, UnitPrice From Products Where CategoryID=@catID" cmdSelect = New SqlCommand( strSelect, conNorthwind ) cmdSelect.Parameters.Add( "@catID", intCatID ) dtrProducts = cmdSelect.ExecuteReader() rptProducts.DataSource = dtrProducts rptProducts.DataBind() dtrProducts.Close() conNorthwind.Close() End Sub Sub dropCategories_SelectedIndexChanged( s As Object, e As EventArgs ) Dim intCatID As Integer intCatID = dropCategories.SelectedItem.Value If intCatID <> ‐1 Then BindProducts( intCatID ) End If End Sub </Script> <html> <head><title>MasterDetail.aspx</title></head> <body> <form Runat="Server"> <b>Select Category:</b> <asp:DropDownList ID="dropCategories" AutoPostBack="True" OnSelectedIndexChanged="dropCategories_SelectedIndexChanged" Runat="Server"/> <p> <asp:Repeater ID="rptProducts" EnableViewState="False" Runat="Server"> <ItemTemplate> <li><%# Container.DataItem( "ProductName" ) %> ‐ <%# String.Format( "{0:c}", Container.DataItem( "UnitPrice" ) ) %> </ItemTemplate> </asp:Repeater> </form> </body> </html> Creating Multipage Master/Detail Forms Instead of placing the master and detail information on the same page, you might want to place
the information on separate pages. For example, suppose you want to create one page that
contains a directory of employees who work at your company and a separate page that lists
details for each employee.
<%@ Import Namespace="System.Data.SqlClient" %>
<Script Runat="Server">
Sub Page_Load
Dim conNorthwind As SqlConnection
Dim cmdSelect As SqlCommand
Dim dtrEmployees As SqlDataReader
conNorthwind = New SqlConnection(
"Server=localhost;UID=sa;PWD=secret;Database=Northwind" )
cmdSelect = New SqlCommand( "Select EmployeeID,LastName From Employees",
conNorthwind )
conNorthwind.Open()
dtrEmployees = cmdSelect.ExecuteReader()
rptEmployees.DataSource = dtrEmployees
rptEmployees.DataBind()
dtrEmployees.Close()
conNorthwind.Close()
End Sub
</Script>
<html>
<head><title>Master.aspx</title></head>
<body>
<form Runat="Server">
<h2>Employee Directory</h2>
<asp:Repeater
ID="rptEmployees"
Runat="Server">
<ItemTemplate>
<li>
<a href='<%# String.Format( "details.aspx?id={0}", Container.DataItem(
"EmployeeID" ) )
%>'><%#
Container.DataItem( "LastName" ) %></a>
</ItemTemplate>
</asp:Repeater>
</form>
</body>
</html>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<Script Runat="Server">
Sub Page_Load
Dim intEmployeeID As Integer
Dim conNorthwind As SqlConnection
Dim strSelect As String
Dim cmdSelect As SqlCommand
Dim dtrEmployee As SqlDataReader
' Retrieve Employee ID
intEmployeeID = Int32.Parse( Request.QueryString( "id" ) )
' Get Employee Detail Information
conNorthwind = New SqlConnection(
"Server=localhost;UID=sa;PWD=secret;Database=Northwind" )
strSelect = "Select * From Employees Where EmployeeID=@employeeID"
cmdSelect = New SqlCommand( strSelect, conNorthwind )
cmdSelect.Parameters.Add( "@employeeID", intEmployeeID )
conNorthwind.Open()
dtrEmployee = cmdSelect.ExecuteReader( CommandBehavior.SingleRow )
' Display in Label Controls
If dtrEmployee.Read Then
lblEmployee.Text = dtrEmployee( "LastName" )
lblEmployee.Text &= ", " & dtrEmployee( "FirstName" )
lblPhone.Text = dtrEmployee( "HomePhone" )
lblAddress.Text = dtrEmployee( "Address" )
lblCity.Text = dtrEmployee( "City" ) & ", "
lblRegion.Text = dtrEmployee( "Region" ).ToString()
lblPostalCode.Text = dtrEmployee( "PostalCode" )
End If
dtrEmployee.Close()
conNorthwind.Close()
End Sub
</Script>
<html>
<head><title>Details.aspx</title></head>
<body>
<form Runat="Server">
<h2>
<asp:Label
ID="lblEmployee"
Runat="Server"/>
</h2>
<p>
<b>Phone:</b>
<blockquote>
<asp:Label
ID="lblPhone"
Runat="Server" />
</blockquote>
<b>Address:</b>
<blockquote>
<asp:Label
ID="lblAddress"
Runat="Server" />
<br>
<asp:Label
ID="lblCity"
Runat="Server" />
<asp:Label
ID="lblRegion"
Runat="Server" />
&nbsp;&nbsp;
<asp:Label
ID="lblPostalCode"
Runat="Server" />
</blockquote>
</form>
</body>
</html>
Data Binding without Data Binding Expressions Earlier in this chapter, when we bound the contents of a database table to a Repeater control, we
used data binding expressions in the Repeater control's ItemTemplate to display the values
retrieved from the database. In this section, we examine how you can avoid using data binding
expressions in templates.
Why would you want to avoid using data binding expressions? There is nothing wrong with
using data binding expressions, and you can always use data binding expressions if you prefer.
However, you'll discover that when you need to perform complicated actions inside a template,
your code can be more readable when you avoid using data binding expressions.
The trick for avoiding data binding expressions is to handle the ItemDataBound event of the
Repeater control. The ItemDataBound event is raised for each item retrieved from the data
source. So, if you are binding a Repeater control to a database table that contains 11 authors,
then the ItemDataBound event is raised 11 times—once for each author.
<%@ Import Namespace="System.Data.SqlClient" %>
<Script Runat="Server">
Sub Page_Load
Dim conPubs As SqlConnection
Dim cmdSelect As SqlCommand
Dim dtrAuthors As SqlDataReader
' Retrieve records from database
conPubs = New SqlConnection(
"Server=localhost;UID=sa;PWD=secret;Database=Pubs" )
cmdSelect = New SqlCommand( "Select * From Authors", conPubs )
conPubs.Open()
dtrAuthors = cmdSelect.ExecuteReader()
' Bind to Repeater
rptAuthors.DataSource = dtrAuthors
rptAuthors.DataBind()
dtrAuthors.Close()
conPubs.Close()
End Sub
Sub Repeater_ItemDataBound(s As Object, e As RepeaterItemEventArgs)
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType =
ListItemType.AlternatingItem
Then
Dim lblAuthor As Label = e.Item.FindControl( "lblAuthor" )
lblAuthor.Text = e.Item.DataItem( "au_lname" )
End If
End Sub
</Script>
<html>
<head><title>Repeater.aspx</title></head>
<body>
<form Runat="Server">
<asp:Repeater
ID="rptAuthors"
OnItemDataBound="Repeater_ItemDataBound"
Runat="Server">
<ItemTemplate>
<asp:Label id="lblAuthor" Runat="Server"/>
</ItemTemplate>
</asp:Repeater>
</form>
</body>
</html>
the Repeater_ItemDataBound subroutine is associated with the Repeater control's ItemDataBound event. This subroutine first checks whether it is being called for an ItemTemplate or AlternatingItemTemplate (we want to skip other types of templates such as the HeaderTemplate). Next, the subroutine uses the FindControl() method to retrieve the lblAuthor Label control from the template. Finally, the value of the current DataItem is assigned to the Label.