Tải bản đầy đủ (.pdf) (10 trang)

Professional ASP.NET 3.5 in C# and Visual Basic Part 42 ppt

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (102.47 KB, 10 trang )

Evjen c07.tex V2 - 01/28/2008 2:01pm Page 365
Chapter 7: Data Binding in ASP.NET 3.5
<
asp:Label ID="CountryLabel" Runat="server"
Text=’
<
%# Bind("Country") %
>

>
<
/asp:Label
><
/td
>
<
td style="width: 100px"
><
/td
>
<
td style="width: 100px"
>
Phone:
<
asp:Label ID="PhoneLabel" Runat="server"
Text=’
<
%# Bind("Phone") %
>


>
<
/asp:Label
><
br /
>
Fax:
<
asp:Label ID="FaxLabel" Runat="server"
Text=’
<
%# Bind("Fax") %
>

>
<
/asp:Label
><
br /
>
<
/td
>
<
/tr
><
/table
>
<
asp:Button ID="Button1" Runat="server"

Text="Button" CommandName="edit" /
>
<
/td
>
<
/tr
><
/table
>
<
/ItemTemplate
>
<
/asp:FormView
>
<
asp:SqlDataSource ID="SqlDataSource1" Runat="server"
SelectCommand="SELECT * FROM [Customers]"
ConnectionString="
<
%$ ConnectionStrings:AppConnectionString1 %
>
"
>
<
/asp:SqlDataSource
>
<
/div

>
<
/form
>
<
/body
>
<
/html
>
Other Databound Controls
ASP.NET 1.0/1.1 contained many other controls that could be bound to data sources. ASP.NET 2.0
retained those controls, enhanced some, and added several additional bound controls to the toolbox
ASP.NET 3.5 continues to include these controls in its toolbox.
DropDownList, ListBox, RadioButtonList, and CheckBoxList
Although the DropDownList, ListBox, and CheckBoxList controls largely remained the same from
ASP.NET 1.0/1.1 to ASP.NET 2.0, several new properties that you might find useful were added. In addi-
tion, ASP.NET 2.0 added new RadioButtonList and BulletedList controls. All of these controls remain the
same in ASP.NET 3.5.
One of the new properties available in all these controls is the
AppendDataBoundItems
property. Setting
this property to
True
tells the DropDownList control to append data-bound list items to any exist-
ing statically declared items, rather then overwriting them as the ASP.NET 1.0/1.1 version would
have done.
Another useful new property available to all these controls is the
DataTextFormatString
, which allows

you to specify a string format for the display text of the DropDownList items.
365
Evjen c07.tex V2 - 01/28/2008 2:01pm Page 366
Chapter 7: Data Binding in ASP.NET 3.5
TreeView
Another control included in the ASP.NET toolbox is the TreeView control. Because the TreeView can
display only hierarchical data, it can be bound only to the XmlDataSource and the SiteMapDataSource
controls. Listing 7-59 shows a sample SiteMap file you can use for your SiteMapDataSource control.
Listing 7-59: A SiteMap file for your samples
<
siteMap
>
<
siteMapNode url="page3.aspx" title="Home" description="" roles=""
>
<
siteMapNode url="page2.aspx" title="Content" description="" roles="" /
>
<
siteMapNode url="page4.aspx" title="Links" description="" roles="" /
>
<
siteMapNode url="page1.aspx" title="Comments" description="" roles="" /
>
<
/siteMapNode
>
<
/siteMap
>

Listing 7-60 shows how you can bind a TreeView control to a SiteMapDataSource control to generate
navigation for your Web site.
Listing 7-60: Using the TreeView with a SqlDataSource control
<
%@ Page Language="C#" %
>
<
html xmlns=" />>
<
head runat="server"
>
<
title
>
Using the TreeView control
<
/title
>
<
/head
>
<
body
>
<
form id="form1" runat="server"
>
<
div
>

<
asp:TreeView ID="TreeView1" Runat="server"
DataSourceID="SiteMapDataSource1"
>
<
/asp:TreeView
>
<
asp:SiteMapDataSource ID="SiteMapDataSource1" Runat="server" /
>
<
/div
>
<
/form
>
<
/body
>
<
/html
>
Ad Rotator
The familiar AdRotator control was greatly enhanced in ASP.NET 2.0. Y ou can see the control by
using the SqlDataSource or XmlDataSource controls. Listing 7-61 shows an example of binding the AdRo-
tator to a SqlDataSource control.
Listing 7-61: Using the AdRotator with a SqlDataSource control
<
asp:AdRotator ID="AdRotator1" runat="server"
DataSourceId="SqlDataSource1" AlternateTextField="AlternateTF"

ImageUrlField="Image" NavigateUrlField="NavigateUrl" /
>
For more information on the Ad Rotator control, see Chapter 5.
366
Evjen c07.tex V2 - 01/28/2008 2:01pm Page 367
Chapter 7: Data Binding in ASP.NET 3.5
Menu
The last control in this section is the new Menu control. Like the TreeView control, it is capable of
displaying hierarchical data in a vertical pop-out style menu. Also like the TreeView control, it can be
bound only to the XmlDataSource and the SiteMapDataSource controls. Listing 7-62 shows how you can
use the same SiteMap data used earlier in the TreeView control sample, and modify it to display using
the new Menu control.
Listing 7-62: Using the Menu control with a SiteMap
<
%@ Page Language="C#" %
>
<
html xmlns=" />>
<
head runat="server"
>
<
title
>
Using the Menu control
<
/title
>
<
/head

>
<
body
>
<
form id="form1" runat="server"
>
<
div
>
<
asp:Menu ID="Menu1" Runat="server" DataSourceID="SiteMapDataSource1"
>
<
/asp:Menu
>
<
asp:SiteMapDataSource ID="SiteMapDataSource1" Runat="server" /
>
<
/div
>
<
/form
>
<
/body
>
<
/html

>
For more information on using t he Menu control, see Chapter 14.
Inline Data-Binding Syntax
Another feature of data binding in ASP.NET is inline data-binding syntax. Inline syntax in ASP.NET
1.0/1.1 was primarily relegated to templated controls such as the DataList or the Repeater controls, and
even then it was sometimes difficult and confusing to make it work as you wanted it to. In ASP.NET
1.0/1.1, if you needed to use inline data binding, you might have created something like the procedure
shown in Listing 7-63.
Listing 7-63: Using DataBinders in ASP.NET 1.0
<
asp:Repeater id=Repeater1 runat="server"
>
<
HeaderTemplate
>
<
table
>
<
/HeaderTemplate
>
<
ItemTemplate
>
<
tr
>
<
td
>

<
%# Container.DataItem("Name") %
><
BR/
>
<
%# Container.DataItem("Department") %
><
BR/
>
<
%# DataBinder.Eval(
Container.DataItem, "HireDate", "{0:mm dd yyyy}") %
><
BR/
>
<
/td
>
Continued
367
Evjen c07.tex V2 - 01/28/2008 2:01pm Page 368
Chapter 7: Data Binding in ASP.NET 3.5
<
/tr
>
<
/ItemTemplate
>
<

FooterTemplate
>
<
/table
>
<
/FooterTemplate
>
<
/asp:Repeater
>
As you can see in this sample, you are using a Repeater control to display a series of employees. Because
the Repeater control is a templated control, you use data binding to output the employee-specific data
in the proper location of the template. Using the
Eval
method also allows you to provide formatting
information such as Date or Currency formatting at render-time.
In later versions of ASP.NET, including 3.5, the concept of inline data binding remains basically the same,
but you are given a simpler syntax and several powerful new binding tools to use.
Data-Binding Syntax Changes
ASP.NET contains three different ways to perform data binding. First, you can continue to use the exist-
ing method of binding, using the
Container.DataItem
syntax:
<
%# Container.DataItem("Name") %
>
This is good because it means you w on’t have to change your existing Web pages if you are migrating
from prior versions of ASP.NET. But if you are creating new Web pages, you should probably use the
simplest form of binding, using the

Eval
method directly:
<
%# Eval("Name") %
>
You can also continue to format data using the formatter overload of the
Eval
method:
<
%# Eval("HireDate", "{0:mm dd yyyy}" ) %
>
In addition to these changes, ASP.NET includes a form of data binding called two-way data binding.In
ASP.NET 1.0/1.1, using the data-binding syntax was essentially a read-only form of accessing data.
Since the introduction of ASP.NET 2.0, two-way data binding has allowed you to support both read and
write operations for bound data. This is done using the
Bind
method, which, other than using a different
method name, works just like the
Eval
method:
<
%# Bind("Name") %
>
The new
Bind
method should be used in new controls such as the GridView, DetailsView, or FormView,
where auto-updates to the data source are implemented.
When working with the data binding statements, remember that anything between the
<
%# %

> delimiters
is treated as an expression. This is important because it gives you additional functionality when data
binding. For example, you could append additional data:
<
%# "Foo " + Eval("Name") %
>
Or you can even pass the evaluated value to a method:
<
%# DoSomeProcess( Eval("Name") )%
>
368
Evjen c07.tex V2 - 01/28/2008 2:01pm Page 369
Chapter 7: Data Binding in ASP.NET 3.5
XML Data Binding
Because XML is becoming ever more prevalent in applications, ASP.NET also includes several ways to
bind specifically to XML data sources. These new data binding expressions give you powerful ways of
working with the hierarchical format of XML. Additionally, except for the different method names, these
binding methods work exactly the same as the
Eval
and
Bind
methods discussed earlier. These binders
should be used when you are using the XmlDataSource control. The first binding format that uses the
XPathBinder
class is shown in the following code:
<
% XPathBinder.Eval(Container.DataItem, "employees/employee/Name") %
>
Notice that rather than specifying a column name as in the
Eval

method, the
XPathBinder
binds the
result of an XPath query. Like the standard
Eval
expression, the XPath data binding expression also has
a shorthand format:
<
% XPath("employees/employee/Name") %
>
Also, like the
Eval
method, the XPath data binding expression supports applying formatting to the data:
<
% XPath("employees/employee/HireDate", "{0:mm dd yyyy}") %
>
The
XPathBinder
returns a single node using the XPath query provided. Should you want to return
multiple nodes from the XmlDataSource Control, you can use the class’s
Select
method.Thismethod
returns a list of nodes that match the supplied XPath query:
<
% XPathBinder.Select(Container.DataItem,"employees/employee") %
>
Or use the shorthand syntax:
<
% XpathSelect("employees/employee") %
>

Expressions and Expression Builders
Finally, ASP.NET introduces the concept of expressions and expression builders. Expressions are state-
ments that a re parsed by ASP.NET at runtime in order to return a data value. ASP.NET automatically
uses expressions to do things like retrieve the database connection string when it parses the SqlData-
Source control, so you may have already seen these statements in your pages. An example of the connec-
tion string Expression is shown in Listing 7-64.
Listing 7-64: A connection string Expression
<
asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="
<
%$ ConnectionStrings:NorthwindConnectionString %
>
"
SelectCommand="SELECT * FROM Customers"
><
/asp:SqlDataSource
>
When ASP.NET is attempting to parse an ASP.NET Web page, it looks for expressions contained in the
<
%$ %
>delimiters. This indicates to ASP.NET that this is an expression to be parsed. As shown in the
previous listing, it attempts to locate the
NorthwindConnectionString
value from the web.config file.
ASP.NET knows to do this because of the
ConnectionStrings
expression prefix, which tells ASP.NET to
use the
ConnectionStringsExpressionBuilder

class to parse the expression.
369
Evjen c07.tex V2 - 01/28/2008 2:01pm Page 370
Chapter 7: Data Binding in ASP.NET 3.5
ASP.NET includes several expression builders, including one for retrieving values from the AppSet-
tings section of
web.config
: one for retrieving ConnectionStrings as shown in Listing 7-64, and one for
retrieving localized resource file values. Listings 7-65 and 7-66 demonstrate using the
AppSettingsEx-
pressionBuilder
and the
ResourceExpressionBuilder
.
Listing 7-65: Using AppSettingsExpressionBuilder
<
asp:Label runat="server" ID="lblAppSettings"
Text="
<
%$ AppSettings: LabelText %
>
"
><
/asp:Label
>
Listing 7-66: Using ResourceExpressionBuilder
<
asp:Label runat="server" ID="lblResource"
Text="
<

%$ Resources: TEST %
>
"
><
/asp:Label
>
In addition to using the expression builder classes, you can also create your own expressions by deriving
aclassfromthe
System.Web.Compilation.ExpressionBuilder
base class. This base class provides you
with the overridable methods you need to implement if you want ASP.NET to parse your expression
properly. Listing 7-67 shows a simple custom expression builder.
Listing 7-67: Using a simple custom expression builder
VB
Imports System;
Imports System.CodeDom;
Imports System.Web.Compilation;
Imports System.Web.UI;
<
ExpressionPrefix("MyCustomExpression")
>
<
ExpressionEditor("MyCustomExpressionEditor")
>
Public Class MyCustomExpression Inherits ExpressionBuilder
Public Overrides Function
GetCodeExpression(ByVal entry As BoundPropertyEntry,
ByVal parsedData As object, ByVal context As ExpressionBuilderContext)
As System.CodeDom.CodeExpression
Return New CodeCastExpression("Int64", new CodePrimitiveExpression(1000))

End Function
End Class
C#
using System;
using System.CodeDom;
using System.Web.Compilation;
using System.Web.UI;
[ExpressionPrefix("MyCustomExpression")]
[ExpressionEditor("MyCustomExpressionEditor")]
public class MyCustomExpression : ExpressionBuilder
{
public override System.CodeDom.CodeExpression
370
Evjen c07.tex V2 - 01/28/2008 2:01pm Page 371
Chapter 7: Data Binding in ASP.NET 3.5
GetCodeExpression(BoundPropertyEntry entry, object parsedData,
ExpressionBuilderContext context)
{
return new CodeCastExpression("Int64", new CodePrimitiveExpression(1000));
}
}
In examining this sample, notice several items. First, you have derived the
MyCustomExpression
class
from
ExpressionBuilder
as I discussed earlier. Second, you have overridden the
GetCodeExpression
method. This method supplies you with several parameters that can be helpful in executing this method,
and it returns a

CodeExpression
object to ASP.NET that it can execute at runtime to retrieve the data
value.
The
CodeExpression
class is a base class in .NET’s CodeDom infrastructure. Classes that are derived
from the
CodeExpression
class provide abstracted ways of generating .NET code, whether VB or C#.
This CodeDom infrastructure is what helps you create and run code dynamically at runtime.
The
BoundPropertyEntry
parameter entry tells you exactly which property the expression is bound
to. For example, in Listings 7-58 and 7-59, the Label’s
Text
property is bound to the
AppSettings
and
Resources
expressions. The object parameter
parsedData
contains any data that was parsed and returned
by the
ParseExpression
method that you see later on in the chapter. Finally, the
ExpressionBuilder-
Context
parameter context allows you to reference the virtual path or templated control associated with
the expression.
In the body of the

GetCodeExpression
method, you are creating a new
CodeCastExpression
object,
whichisaclassderivedfromthe
CodeExpression
base class. The
CodeCastExpression
tells .NET to
generate the appropriate code to execute a cast from one data type to another. In this case, you are casting
the value 1000 to an Int64 datatype. When .NET executes the
CodeCastExpression
,itis(inasense)
writing the C# code ((long)(1000)), or (if your application was written in VB) CType(1000,Long). Note
that a wide variety of classes derive from the
CodeExpression
class that you can use to generate your
final code expression.
The final lines to note are the two attributes that have been added to the class. The
ExpressionPrefix
and
ExpressionEditor
attributes help .NET figure out that this class should be used as an expression, and
they also help .NET locate the proper expression builder class when it comes time to parse the expression.
After you have created your expression builder class, you let .NET know about it. You do this by adding
an
expressionBuilders
node to the compilation node in your
web.config
file. Notice that the value

of the
ExpressionPrefix
is added to the
expressionBuilder
to help ASP.NET locate the appropriate
expression builder class at runtime.
<
compilation debug="true" strict="false" explicit="true"
>
<
expressionBuilders
>
<
add expressionPrefix="MyCustomExpression" type="MyCustomExpression"/
>
<
/expressionBuilders
>
<
/compilation
>
The
GetCodeExpression
method is not the only member available for overriding in the
Expression-
Builder
class. Several other useful members include the
ParseExpression
,
SupportsEvaluate

,and
EvaluateExpression
methods.
371
Evjen c07.tex V2 - 01/28/2008 2:01pm Page 372
Chapter 7: Data Binding in ASP.NET 3.5
The
ParseExpression
method lets you pass parsed expression data into the
GetCodeExpression
method.
For example, in Listing 7-60, the
CodeCastExpression
value 1000 was hard-coded. If, however, you want
to allow a developer to pass that value in as part of the expression, you simply use the
ParseExpression
method as shown in Listing 7-68
Listing 7-68: Using ParseExpression
VB
Imports System;
Imports System.CodeDom;
Imports System.Web.Compilation;
Imports System.Web.UI;
<
ExpressionPrefix("MyCustomExpression")
>
<
ExpressionEditor("MyCustomExpressionEditor")
>
Public Class MyCustomExpression Inherits ExpressionBuilder

Public Overrides Function
GetCodeExpression(ByVal entry As BoundPropertyEntry,
ByVal parsedData As object, ByVal context As ExpressionBuilderContext)
As System.CodeDom.CodeExpression
Return New CodeCastExpression("Int64",
new CodePrimitiveExpression(passedData))
End Function
Public Overrides Function ParseExpression
(ByVal expression As String, ByVal propertyType As Type,
ByVal context As ExpressionBuilderContext) As Object
Return expression
End Function
End Class
C#
using System;
using System.CodeDom;
using System.Web.Compilation;
using System.Web.UI;
[ExpressionPrefix("MyCustomExpression")]
[ExpressionEditor("MyCustomExpressionEditor")]
public class MyCustomExpression : ExpressionBuilder
{
public override System.CodeDom.CodeExpression
GetCodeExpression(BoundPropertyEntry entry, object parsedData,
ExpressionBuilderContext context)
{
return new CodeCastExpression("Int64",
new CodePrimitiveExpression(parsedData));
}
372

Evjen c07.tex V2 - 01/28/2008 2:01pm Page 373
Chapter 7: Data Binding in ASP.NET 3.5
public override object ParseExpression
(string expression, Type propertyType, ExpressionBuilderContext context)
{
return expression;
}
}
The last two
ExpressionBuilder
overrides to examine are the
SupportsEvaluate
and
EvaluateExpres-
sion
members. You need to override these methods if you are running your Web site in a no-compile
scenario (you have specified
compilationMode = "never"
in your @Page directive). The
SupportEvalu-
ate
property returns a Boolean indicating to ASP.NET whether this expression can be evaluated while a
page is executing in no-compile mode. If
True
is returned and the page is executing in no-compile mo de,
the
EvaluateExpression
method is used to return the data value rather than the
GetCodeExpression
method. The

EvaluateExpression
returns an object representing the data value. See Listing 7-69.
Listing 7-69: Overriding SupportsEvaluate and EvaluateExpression
VB
Imports System;
Imports System.CodeDom;
Imports System.Web.Compilation;
Imports System.Web.UI;
<
ExpressionPrefix("MyCustomExpression")
>
<
ExpressionEditor("MyCustomExpressionEditor")
>
Public Class MyCustomExpression Inherits ExpressionBuilder
Public Overrides Function
GetCodeExpression(ByVal entry As BoundPropertyEntry,
ByVal parsedData As object, ByVal context As ExpressionBuilderContext)
As System.CodeDom.CodeExpression
Return New CodeCastExpression("Int64",
new CodePrimitiveExpression(pasedData))
End Function
Public Overrides Function ParseExpression
(ByVal expression As String, ByVal propertyType As Type,
ByVal context As ExpressionBuilderContext) As Object
Return expression
End Function
Public Overrides ReadOnly Property SupportsEvaluate as Boolean
Get
Return True

End Get
End Property
Public Overrides Function EvaluateExpression(ByVal target As Object,
ByVal Entry As BoundPropertyEntry, ByVal parsedData As Object,
ByVal context As ExpressionBuilderContext) as Object
Continued
373
Evjen c07.tex V2 - 01/28/2008 2:01pm Page 374
Chapter 7: Data Binding in ASP.NET 3.5
Return parsedData;
End Function
End Class
C#
using System;
using System.CodeDom;
using System.Web.Compilation;
using System.Web.UI;
[ExpressionPrefix("MyCustomExpression")]
[ExpressionEditor("MyCustomExpression123Editor")]
public class MyCustomExpression : ExpressionBuilder
{
public override System.CodeDom.CodeExpression
GetCodeExpression(BoundPropertyEntry entry, object parsedData,
ExpressionBuilderContext context)
{
return new CodeCastExpression("Int64",
new CodePrimitiveExpression(parsedData));
}
public override object ParseExpression
(string expression, Type propertyType, ExpressionBuilderContext context)

{
return expression;
}
public override bool SupportsEvaluate
{
get
{
return true;
}
}
public override object EvaluateExpression(object target,
BoundPropertyEntry entry, object parsedData,
ExpressionBuilderContext context)
{
return parsedData;
}
}
As shown in Listing 7-69, you can simply return
True
from the
SupportsEvaluate
property if you want
to override the
EvaluateExpression
method.Thenallyoudoisreturnanobjectfromthe
EvaluateEx-
pression
method.
374

×