Quang Hung 的个人资料Quang Hung's space照片日志网络更多 ![]() | 帮助 |
|
|
12月1日 add style sheet to page Just add a runat attribute to your traditional link tag. ID attribute has to be present, and tag has to be properly closed (not like HTML).<head> <link id="MyStyleSheet" rel="stylesheet" type="text/css" runat="server" /> </head>Then in your Page_Load, simply add a "href" attribute as below:Sub Page_Load(Sender As Object, E As EventArgs) If Not (IsPostBack) MyStyleSheet.Attributes.Add("href","/css/flostyle.css") End If End SubHope this helps -- Bruno Alexandre (a Portuguese in Københanv, Danmark) <> escreveu na mensagem news: oups.com... I'm afraid I can't use 2.0. Is this not possible in 1.1? Bruno Alexandre wrote: 11月14日 Convert SQLServer2005 to SQLServer2000
11月13日 Change text of Label in Master page at runtimeTry this snippet - 11月11日 Uploading Files in ASP.NET 2.0Bill Evjen December 2005 Applies to: Microsoft ASP.NET 2.0 Summary: Learn how to use the new FileUpload server control in Microsoft ASP.NET 2.0. (18 printed pages) ContentsIntroduction IntroductionEver since Microsoft ASP.NET was introduced with version 1.0, there has been the built-in means of building Web applications that had the ability to upload files to the hosting server. This was done through the use of the File Field HTML server control. I previously wrote an MSDN article on how to effectively use this control in your ASP.NET applications. This article is a reintroduction to the file upload process, but instead of using the File Field control, I will show you how to effectively use the new FileUpload server control that is offered through ASP.NET 2.0. It is important to note that while this article introduces you to the new FileUpload server control, it is still quite possible to use the File Field control in your applications today. An Example of the FileUpload Server ControlWhen using the File Field control in ASP.NET 1.x you had to take a few extra steps to get everything in line and working. For example, you were required to add enctype="multipart/form-data" to the page's <form> element on your own. The new FileUpload server control provided in ASP.NET 2.0 makes the process of uploading files to the hosting server as simple as possible. In the end, you are trying to allow access to program the HTML <input type="file"> tag. This tag is used to work with file data within an HTML form. In the past when using classic ASP (ASP 3.0 or earlier), many programmers worked with third-party components to upload files from the client to the server. Now, with .NET and this new control, uploading is taken care of for you. Listing 1 shows you how to use the FileUpload control to upload files to the server. Note The sample code is provided in both Microsoft Visual Basic and C#. Listing 1. Uploading files to the server using the FileUpload control Visual Basic <%@ Page Language="VB" %> C# <%@ Page Language="C#" %> Running this page, you will notice a few things if you look at the source code generated for the page. This source code is presented in Listing 2. Listing 2. The source code generated from the FileUpload control <html > The first thing to notice is that because the FileUpload control is on the page, ASP.NET 2.0 modified the page's <form> element on your behalf by adding the appropriate enctype attribute. You will also notice that the FileUpload control was converted to an HTML <input type="file"> element. When the page from Listing 1 is run, you can select a file and upload it to the server by clicking the Upload File button on the page. There are some important items we should go over for this example so you understand all the needed pieces to make this work. For the example in Listing 1 to work, you have to make the destination folder on the server writeable for the account used by ASP.NET so the file can be saved to the specified folder. If you think your ASP.NET account is not enabled to write to the folder you want, simply open up Microsoft Windows Explorer and navigate to the folder to which you want to add this permission. Right-click on the folder (in this case, the Uploads folder), and then select Properties. In the Properties dialog box, click on the Security tab and make sure the ASP.NET Machine Account is included in the list and has the proper permissions to write to disk (see Figure 1).
Figure 1. Looking at the Security tab of the Uploads folder If you don't see the ASP.NET Machine Account under the Security tab, you can add it by clicking the Add button and entering ASPNET (without the period) in the text area, as illustrated in Figure 2.
Figure 2. Adding the ASP.NET Machine Account to the folder security definition Click OK to add the ASP.NET Machine Account to the list. From here, make sure you give this account the proper permissions and then click OK, and you are ready to go. The Submit button on the page causes the Button1_Click event to occur. This event uploads the file and then displays a message telling you if the upload was successful by posting information about the file uploaded. If it was unsuccessful, the page displays an error message describing why the upload failed. By using the FileUpload control that converts itself to an <input type="file"> tag, the browser automatically places a Browse button next to the text field on the ASP.NET page. You don't have to program anything else for this to occur. When the end user clicks the Browse button, he can navigate through the local file system to find the file to be uploaded to the server. This is shown in Figure 3. Clicking Open will place that filename and the file's path within the text field.
Figure 3. Choosing a file Working Around File Size LimitationsYou may not realize it, but there is a limit to the size of a file that can be uploaded using this technique. By default, the maximum size of a file to be uploaded to the server using the FileUpload control is around 4MB. You cannot upload anything that is larger than this limit. One of the great things about .NET, however, is that it usually provides a way around limitations. You can usually change the default settings that are in place. To change this size limit, you make some changes in either the web.config.comments (found in the ASP.NET 2.0 configuration folder at C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG) or your application's web.config file. In the web.config.comments file, find a node called <httpRuntime> that looks like the following: <httpRuntime A lot is going on in this single node, but the setting that takes care of the size of the files to be uploaded is the maxRequestLength attribute. By default, this is set to 4096 kilobytes (KB). Simply change this value to increase the size of the files that you can upload to the server. If you want to allow 10 megabyte (MB) files to be uploaded to the server, set the maxRequestLength value to 11264, meaning that the application allows files that are up to 11000 KB to be uploaded to the server. Making this change in the web.config.comments file applies this setting to all the applications that are on the server. If you want to apply this to only the application you are working with, apply this node to the web.config file of your application, overriding any setting that is in the web.config.comments file. Make sure this node resides between the <system.web> nodes in the configuration file. Another setting involved in the size limitation of files to be uploaded is the value given to the executionTimeout attribute in the <httpRuntime> node. The value given the executionTimeout attribute is the number of seconds the upload is allowed to occur before being shut down by ASP.NET. If you are going to allow large files to be uploaded to the server, you are also going to want to increase this value along with the maxRequestLength value. One negative with increasing the size of a file that can be uploaded is that there are hackers out there who attack servers by throwing a large number of requests at them. To guard against this, you can actually decrease the size of the files that are allowed to be uploaded; otherwise, you may find hundreds or even thousands of 10 MB requests hitting your server. Client-Side Validation of File Types Permissible to UploadThere are several methods you can use to control the types of files that are uploaded to the server. Unfortunately, there is no bullet-proof method to protect you from someone uploading files that would be considered malicious. You can take a few steps, however, to make this process of allowing end users to upload files a little more manageable. One nice method you can employ is to use the ASP.NET validation controls that are provided for free with ASP.NET. These controls enable you to do a regular-expression check upon the file that is being uploaded to see if the extension of the file is one you permit to be uploaded. This is ideal for browsers that allow client-side use of the validation controls because it forces the checking to be done on the client; the file is not uploaded to the server if the signature isn't one you allow. Listing 3 shows you an example of using validation controls to accomplish this task. Note The use of validation controls is not explained here. Take a look at Validating ASP.NET Server Controls for a complete explanation of validation controls and how to use them in your ASP.NET pages. Listing 3. Using validation controls to restrict the types of files uploaded to the server <asp:FileUpload ID="FileUpload1" runat="server" /><br /> This simple ASP.NET page uses validation controls so that the end user can only upload .mp3, .mpeg, or .m3u files to the server. If the file type is not one these three choices, a Validation control throws an exception onto the screen. This is shown in Figure 4.
Figure 4. Validating the file type using validation controls Using Validation controls is not a foolproof way of controlling the files that are uploaded to the server. It wouldn't be too hard for someone to change the file extension of a file so it would be accepted and uploaded to the server, thereby bypassing this simple security model. Adding Server-Side File Type ValidationYou just saw an easy way to add some ASP.NET validation server controls to your ASP.NET page to perform a client side validation of the file extension (in just a textual manner). Now let's take a look at how to perform a similar operation on the server-side. This is presented in Listing 4. Listing 4. Checking the file type on the server Visual Basic Protected Sub Button1_Click(ByVal sender As Object, _ C# protected void Button1_Click(object sender, EventArgs e) Now, by using the GetExtension method from the System.IO.Path namespace, you can perform basically the same operation. It is important to note that this doesn't get around an end user's ability to simply change the file extension to something that works and upload that altered file to the hosting server. Uploading Multiple Files at the Same TimeSo far, you have seen some good examples of how to upload a file to the server without much hassle. Now let's take a look at how to upload multiple files to the server from a single page. No built-in capabilities in the Microsoft .NET Framework enable you to upload multiple files from a single ASP.NET page. With a little work, however, you can easily accomplish this task just as you would have in the past using .NET 1.x. The trick is to import the System.IO class into your ASP.NET page, and to then use the HttpFileCollection class to capture all the files that are sent in with the Request object. This approach enables you to upload as many files as you want from a single page. If you wanted to, you could simply handle each and every FileUpload control on the page individually, as presented in Listing 5. Listing 5. Handling each FileUpload control individually Visual Basic If FileUpload1.HasFile Then C# if (FileUpload1.HasFile) { This approach works, but there may be instances where you are going to want to handle the files using the HttpFileCollection class instead—especially if you are working with a dynamically generated list of server controls. For an example of this, you can build an ASP.NET page that has three FileUpload controls and one Submit button (using the Button control). After the user clicks the Submit button and the files are posted to the server, the code behind takes the files and saves them to a specific location on the server. After the files are saved, the file information that was posted is displayed in the ASP.NET page (see Listing 6). Listing 6. Uploading multiple files to the server Visual Basic Protected Sub Button1_Click(ByVal sender As Object, _ C# protected void Button1_Click(object sender, EventArgs e) The end user can select up to four files and click the Upload Files button, which initializes the Button1_Click event. Using the HttpFileCollection class with the Request.Files property lets you gain control over all the files that are uploaded from the page. When the files are in this state, you can do whatever you want with them. In this case, the files' properties are examined and written to the screen. In the end, the files are saved to the Uploads folder in the root directory of the server. The result of this action is illustrated in Figure 5.
Figure 5. Uploading four files at once to the server from a single ASP.NET page As you may have noticed, one interesting point about this example is that the states of the file input text boxes are not saved with the postback. You can see this in Figure 5. In ASP.NET, the state of the file-input text boxes cannot be saved because doing so might pose a security risk. ConclusionThe FileUpload server control provided by ASP.NET is a powerful control that was quite difficult to achieve in the days of Active Server Pages 3.0. This new capability allows your end-users to upload one or more files to your server. Remember, you can control the size of the files that are uploaded by working with settings in either the web.config.comments or web.config file. About the author Bill Evjen is an active proponent of .NET technologies and community-based learning initiatives for .NET. He is a technical director for Reuters, the international news and financial services company based in St. Louis, Missouri. Bill is the founder and executive director of the International .NET Association (INETA), which represents more than 100,000 members worldwide. Bill is also an author and speaker and has written such books as ASP.NET Professional Secrets, XML Web Services for ASP.NET, Web Services Enhancements, and the Visual Basic .NET Bible (all from Wiley). 11月10日 Paging in DataList
Ví dụ lấy trang thứ 5, mỗi trang 10 bài |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <table width=100% align="right"> <tr> <td width=76% align=left> <asp:label ID="lblStatus" Runat="server" Font-Name="verdana" Font-Size="10pt" /> </td> <td width=6%> <a href="datalistpaging.aspx#this" ID="hrefFirst" onserverclick="ShowFirst" runat="server"><<<</a> </td> <td width=6%> <a href="datalistpaging.aspx#this" ID="hrefPrevious" onserverclick="ShowPrevious" runat="server"><<</a> </td> <td width=6%> <a href="datalistpaging.aspx#this" ID="hrefNext" onserverclick="ShowNext" runat="server">></a> </td> <td width=6%> <a href="datalistpaging.aspx#this" ID="hrefLast" onserverclick="ShowLast" runat="server">>></a> </td> </tr> </table> |
Important Note:
The name of the file that I have used in the href property is
"datalistpaging.aspx". You should replace this with your aspx filename,
unless you keep the filename as myself.
We have four
hyperlinks for each navigation. On each of these, we have a
OnServerClick event which will be fired immediately when the user
clicks the link. For example, when the user click the link, <<,
which is for the first page, the method ShowFirst will be invoked. All
we have to do in the ShowFirst method is to set the current record
position to zero. And ofcourse, we have to bind the datalist. Let us
take a look at the methods, ShowFirst and DataBind.
| Public Sub ShowFirst(ByVal s As Object, ByVal e As EventArgs) intCurrIndex.Text = "0" DataBind() End Sub Private Sub DataBind() Dim objConn As New SqlConnection(ConfigurationSettings.AppSettings("ConnectionString")) Dim objDA As New SqlDataAdapter("exec sp_das_sales_sel", objConn) Dim objDS As New DataSet() If Not Page.IsPostBack() Then objDA.Fill(objDS) intRecordCount.Text = CStr(objDS.Tables(0).Rows.Count) objDS = Nothing objDS = New DataSet() End If objDA.Fill (objDS, Cint(intCurrIndex.Text), CInt(intPageSize.Text), "Sales") dList.DataSource = objDS.Tables(0).DefaultView dList.DataBind() objConn.Close() PrintStatus() End Sub |
In the ShowFirst
method, we are setting the value of intCurrIndex.Text to be zero.
intCurrIndex is a hidden label control which keeps track of the current
record number. We also do have two more hidden label controls. They are
intPageSize and intRecordCount.
In the method, DataBind
you can see that, we get the total record count. We are storing this
count in the hidden label web server control called, intRecordCount.
Then we use the Fill method to retrieve the current page.
The major disadvantage of our logic is that, if we have 1000 records in the table, we are bringing all those to our ASPX pages. All we need is the records for our current page. This can be achived by modifying our stored procedure. We should have an identity column in our table. Then, we should pass the starting position and the number of records to be retrieved to the stored procedure. By this way, we will just be bringing in the needed records, which will decrease the network traffic and throughput time.

Fig: Paging in DataList.
Test this Script
Click here to download the ASPX page
Click here to download the Stored Procedure
So, that is it. We have a datalist with paging mechanism. Also read my other article which explains adding the sort feature to a datalist.
Send your comments to das@aspalliance.com
| Introduction | |
|
[ Back To Top ] Themes are used to define visual styles for web pages. Themes are made up of a set of elements: skins, Cascading Style Sheets (CSS), images, and other resources. Themes can be applied at the application, page, or server control level. We can create theme by adding App_Themes folder in our project in solution explorer panel. The simple steps are Right click on project and select Add ASP.NET folder – Theme. We can add files into it also. The sample code snippets in this article have been written in C#. | |
| Applying Themes | |
|
[ Back To Top ] Applying Theme to a Page A Theme is an attribute of the page class that we can set in various ways. Once the Theme is set, the page ensures that all of its controls will render according to the visual settings defined in the Theme. Listing 1 illustrates how to define a Theme to a page. Listing 1 <% Page Language=“C#” Theme=”myTheme” %>Applying Theme to an Entire Application In addition to applying an ASP.NET 2.0 theme to our ASP.NET pages using the Theme attribute within the page directive, we can also apply it at an application level from the Web.config file. Then the Theme will be applied automatically to each and every page within the application. This is illustrated in Listing 2. Listing 2 <configuration>Applying Theme to all Applications in a Server If we want to use a particular theme for all the web applications in the server, we can do the same. We can specify the theme that we want to use within the machine.config file. This is illustrated in Listing 3. Listing 3 <pages buffer="true" enableSessionState="true"Thus adding the Theme attribute to the pages node within the machine.config file is a great solution for the server having multiple applications using the same Theme. Setting a Theme in the machine.config file means that we do not need to use this theme separately for all the applications on the server. If we specify another Theme in the application's web.config file or in the Web page's Page directive, then settings that are set in the web.config file override settings that are in the machine.config file and settings that are placed in the Page directive override both settings in the machine.config and in the web.config files. | |
| Removing Themes | |
|
[ Back To Top ] Removing Theme from Server Control Whether themes are set at application level or page level, we can set a control’s own style on it. Listing 4 <asp:Textbox ID=”txtTest” Runat=”server”If we apply myTheme at application or page level, the same theme will be applied in all controls except the "txtTest" textbox control as mentioned above. Instead, the backcolor and forecolor, as mentioned in the code snippet, will be applied. Removing Theme from Web Pages If we set the Theme for an entire application in the web.config file and then want to exclude a single ASP.NET page, we can do the same by removing Theme setting at the page level, just like server control. This is illustrated in Listing 5. Listing 5 <% Page Language=“C#” EnableTheming=”false” %>If we make EnableTheming attribute false in the page directive, the Theme defined in web.config file will not be applied in the page. But we can still provide Theme in respect of a specific server control in the same page. This is illustrated in Listing 6. Listing 6 <asp:Textbox ID=”txtTest” Runat=”server” EnableTheming=”true” Theme=” myTheme”/>Theme vs. StylesheetTheme The Page directive also includes the attribute StylesheetTheme that we can use to apply themes to a page. So, the big question is: If we have a Theme attribute and a Stylesheet attribute for the page directive, what we should use? Listing 7 <% Page Language=“C#” StylesheetTheme =”myTheme” %>The StylesheetTheme attribute works the same as the Theme attribute to apply a Theme to a page. The difference is that, when attributes are set locally on the page within a particular server control, the attributes are overridden by the theme when we use the Theme attribute. But if we apply pages’s theme using the StylesheetTheme attribute, the locally set attributes of the server control will not be overridden. | |
| Creating Theme | |
|
[ Back To Top ] In order to create Theme for an application, first we need to create a proper folder structure in application. Within the App_Themes folder, we can create an additional Theme Folder for each and every Theme that we might use in application. The reasons to use more than one Theme are because seasons change, day/night changes, different business units, category of user, user preferences, etc. The elements of a Theme Folder can be as follows: · A Single skin file · CSS files · Images Creating a Skin A skin enables us to modify any of the properties applied to the server controls in our ASP.NET page. Skins can work in conjunction with CSS files or images. To create a Theme we can use a single skin file in the Theme Folder. The skin file extension should be always .skin. Listing 8 <asp:Label Runat=”server” ForeColor=”Red” Font-Names=”Verdana” Font-Size=”X-Small”/>As the above example suggest, we need to define a definition for style in respect of each server control in skin file in the application. We can create different skin files in different Theme Folder. Listing 9 <% Page Language=“C#” Theme =”myTheme” %> | |
| Including CSS Files in Theme | |
|
[ Back To Top ] We can provide styles only for server controls using skin file. But ASP.NET pages are made up of HTML controls, raw HTML or raw Text and to implement style for them we need CSS files within Theme Folder. To create a CSS file for Theme we will click Theme Folder and then select Add New Item. In the list of options we should choose the option Style Sheet and will provide a name say test.CSS. When we are using both skin and CSS file, the skin file will take precedence over CSS file for server controls. | |
| Defining Multiple Skin Options | |
|
[ Back To Top ] In .skin file of Theme’s Folder we can create multiple definitions in respect of same server control. To create multiple definitions of a single element we can use the SkinID attribute to differentiate among the definitions. The value of SkinID can be anything. Listing 10 <asp:Textbox Runat=”server” ForeColor=”Blue”In the above code there is no SkinID for the 1st TextBox server control definition that means it will be used as the default style for TextBox Server control. Where SkinID will be used, the particular definition of TextBox Server Control will be used. Listing 11 <% Page Language=“C#” Theme =”myTheme” %> | |
| Working with Themes Programmatically | |
|
[ Back To Top ] In the above code the Theme has been defined at design time, but we can work with the Theme programmatically. Assigning the Pages’s Theme Programmatically In Listing 12 it is illustrated how we can assign the pages' theme programmatically. Listing 12 <script runat =”server”>Assigning a Control’s SkinID Programmatically There is another option to assign a specific server control’s SkinID property programmatically, which is illustrated in Listing 13. Listing 13 <script runat =”server”> | |
| Images in Theme | |
|
[ Back To Top ] Themes enable us to incorporate actual images into the style definitions. A lot of controls use images to create a better visual appearance. We should create an Images folder within the Themes folder itself. Listing 14 <asp:image ID="Image1" When the above reaches the client, the browser will be smart enough to request testImage.jpg from the App_Themes/ myTheme /Images directory (when myTheme is the selected theme). | |
| References | |
|
[ Back To Top ] | |
| Conclusion | |
|
[ Back To Top ] Themes are a powerful addition to the ASP.NET framework. By taking advantage of themes, we can dramatically reduce the amount of content that we need to add to individual ASP.NET pages. Themes enable us to define the appearance of a control once and apply the appearance throughout a Web application. Therefore, themes enable us to easily create Web sites that have a consistent and maintainable design. This improves the maintainability of our site and avoids unnecessary duplication of code for shared styles. |
Code Behind
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim empsByLocation = _
From em In Employee.getEmployees() _
Group em By Key = em.Location Into Group _
Select New With {.Key = Key, .emps = Group} ListView1.DataSource = empsByLocation
ListView1.DataBind()
End Sub
My Employee Class
Public Class Employee
Public _Location As String
Public _Name As String
Public _Phone As String
Public _ID As Long
Public Sub New(ByVal ID As Long, ByVal Name As String, ByVal Phone As String, ByVal Location As String)
Me._Location = Location
Me._Name = Name
Me._Phone = Phone
Me._ID = ID
End Sub
Public ReadOnly Property Name() As String
Get
Return _Name
End Get
End Property Public ReadOnly Property Location() As String
Get
Return _Location
End Get
End Property
Public Shared Function getEmployees() As List(Of Employee)
Dim employees As New List(Of Employee)
employees.Add(New Employee(1, "Bob", "09809809", "California"))
employees.Add(New Employee(2, "Jack", "3453465", "California"))
employees.Add(New Employee(3, "Arnold", "7899878978", "California"))
employees.Add(New Employee(4, "Barry", "2134678", "Arizona"))
employees.Add(New Employee(5, "Titch", "454458", "Arizona"))
employees.Add(New Employee(6, "Mick", "23432424", "Arizona"))
Return employees
End Function End Class
Will produce the output:
| California |
|
| Arizona |
|
Imagine that you have a database table named Players with a list of basketball players
from the NBA. The schema for this table might look as follows:
Players
| |
|---|---|
FullName | varchar(50)
|
Team | varchar(20)
|
| Improving the Data Model... |
The schema for the Players table is extremely simple and far from
ideal. If this were a "real" database application, we'd likely have a plethora of
additional attributes for a player. Also, we'd likely want a PlayerID
primary key field to uniquely identify each player (since a player's name is not a
guarantee unique attribute). Furthermore, we'd likely have a separate table to
store information about each NBA team, and then have the Team attribute
in the Players table be a foreign key.
|
Given this table schema, imagine that we have the following records:
Now, imagine that you wanted to display the NBA players such that the players for each team
were grouped together. Clearly, a simple SQL query with an appropriate ORDER BY
clause will get all of the players ordered by team. That is, the following query:
|
SELECT FullName, Team FROM Players ORDER BY Team |
Will return all the players playing for the Kings, followed by all the players playing for the Lakers, followed by all the players playing for the Spurs. Specifically, the results of the above SQL query, when run on the sample data, will be as follows:
Therefore, we could have a DataGrid display the name of each player, followed by their team name. However, what if we wanted the display to be a bit different. Rather than blandly list each player and his associated team, we want to list, in big bold letters, the name of the team, followed by all of its players. That is, we want the results to look something like:
Kings |
| Vlade Divac |
| Chris Webber |
| Mike Bibby |
| Doug Christie |
Lakers |
| Shaq |
| Rick Fox |
| Kobe Bryant |
| Robert Horry |
Spurs |
| Tim Duncan |
| Terry Parker |
| David Robinson |
Can we get a DataGrid to render this "style" of output? Sure, if we use a TemplateColumn and a bit of clever programming. We could also obtain such an appearance through the use of a master/detail-type DataGrid, which is discussed in detail in An Extensive Examination of the DataGrid Web Control: Part 14.
In using template, we can implement this sort of display through the use of a DataList and a custom function as well. For this FAQ, let's use the DataList approach.
| DataGrid or DataList? |
Note that a DataList probably makes more sense here since it is designed for
templated columns. Furthermore, the DataList allows for repeated columns via its
RepeatColumns property, meaning you could display the teams n to
a table column. However, if you need functionality like pagination, then
the DataGrid would be a better choice.
|
Using a DataList to Display the Players, Grouped By Team
Imagine, for a moment, that we only want to display the players for each team, and we're not yet worried about displaying the
team name before the list of players. To accomplish this, we could use the following simple DataList:
|
<asp:DataList runat="server" id="dlPlayers"> <ItemTemplate> Container.DataItem("FullName") </ItemTemplate> </asp:DataList> |
This DataList will display a table row and column for each player. Now, to display the team name, we need to be able to determine when the team name switches from one team to the next. That is, when we first start by displaying the players for the Kings, we want to emit the team name Kings and then the player's name, but then for each of the remaining players who play for the Kings, we only want to emit their name. When the first player for the next team (the Lakers) is displayed, again, we want to display both the team name and the player's name; however, for the remaining Lakers players we only want to display the player's name.
In the FAQ, Customizing the Appearance of a DataGrid Column Value,
we saw how to use a custom function to output a custom value based on the value of a DataSource
field. We'll use
this technique in this exercise to emit the player's team name if the
team name has switched from a previous value to a new value.
This can be accomplished with the following code:
|
<script runat="server" language="VB"> ... Function DisplayTeamIfNeeded(team as String) as String Dim output as String = String.Empty 'Determine if this team has yet to be displayed If team <> lastUsedTeam then 'Set that the lastUsedTeam is the current team value lastUsedTeam = team 'Display the team name output = "<br /><b>" &amp; team &amp; "</b><br />" End If Return output End Function </script> <asp:DataList runat="server" id="dlPlayers"> <ItemTemplate> <%# DisplayTeamIfNeeded(Container.DataItem("Team")) %> <%# Container.DataItem("Player") %> </ItemTemplate> </asp:DataList> |
| VB.NET |
|
<script runat="server" language="C#"> <script runat="server" language="C#"> ... string lastUsedTeam = String.Empty; string DisplayTeamIfNeeded(string team) { string output = String.Empty; // Determine if this team has yet to be displayed if (team != lastUsedTeam) { // Set that the lastUsedTeam is the current team value lastUsedTeam = team; // Display the team name output = "<br /><b>" + team + "</b><br />"; } return output; } </script> <asp:DataList runat="server" id="dlPlayers"> <ItemTemplate> <%# DisplayTeamIfNeeded((string) DataBinder.Eval(Container.DataItem, "Team")) %> <%# DataBinder.Eval(Container.DataItem, "Player") %> </ItemTemplate> </asp:DataList> |
| C# |
<asp:ListView ID="..." runat="server" DataSourceID="...">
|
Since the ListView's LayoutTemplate and ItemTemplate are each
defined separately, we need some way to tell the LayoutTemplate, "Hey,
for each
record you are displaying, put the rendered item markup here." This is
accomplished by adding a server-side control with the ID value
specified by the ListView's ItemPlaceholderID
property.
This property defaults to a value of "itemPlaceholder", which is why I
have named the PlaceHolder control in the LayoutTemplate as such.
I could, however, had given the PlaceHolder control an alternate ID, but then I'd need to specify this value in the ListView's
ItemPlaceholdID property.
To output a particular field value in the ItemTemplate, use the databinding syntax, <%# Eval("columnName") %>.
Imagine that the above ListView is bound to an employees database table, and that in the ItemTemplate we were rendering the FullName
column within the <li> element. What would the ListView's rendered markup look like?
Well, the ListView would start by rendering it's LayoutTemplate:
<ol>
|
It would then render its ItemTemplate for each record bound to the ListView control. This might result in the following markup:
<li>Scott Mitchell</li>
|
The ItemTemplate's rendered markup is put in place of the PlaceHolder control (since its ID matches the ListView's ItemPlaceholderID
value. The net result is the following markup:
<ol>
|
An Example of Displaying Simple Data with the ListView
An ASP.NET version 3.5 website is available at the end of this article
with a demo illustrating the ListView control in action. This demo uses
the
Microsoft Access Northwind database, which is included in the demo
application's App_Data folder. The "Simple Data" demo illustrates how to use
the ListView to display records from the Northwind database's Products table. An AccessDataSource control is used to query the Products
table and bind the resulting records to the ListView.
In particular, the ListView starts by displaying
the title "Product Listing" in an <h3> element. It then lists the products within a <blockquote>
element,
which has the effect of indenting the output. Each product has its
name, category, unit price, and quantity per unit displayed. And each
product is separated from one another via a
horizontal rule element (<hr>), which is defined in the ItemSeparatorTemplate.
The ListView and AccessDataSource's declarative markup follows:
<asp:ListView ID="ProductList" runat="server" DataSourceID="ProductDataSource">
|
When this page is visited, the ListView renders into the following HTML:
<h3>Product Listing</h3>
|
Which appears in the visitor's browser like so:
Conclusion
The ListView control, new to ASP.NET 3.5, offers the same rich data
features found in the GridView, but allows for a much more flexible
rendered
output. As we saw in this article, the ListView's rendered output is
based on the markup, databinding expressions, and Web controls added to
its
LayoutTemplate and ItemTemplate. There are a number of other templates
available, as well, and we will explore these along with features like
sorting,
paging, deleting, editing, and inserting in future installments of this
article series.
Until then... Happy Programming!
Currently you can't directly use Linq over and DataSet/DataTable/DataRowCollection/etc. class. Trying something like this won't work:
var q = from r in table.Rows select r;
Enabling Linq over the classes mentioned above is under consideration by Microsoft and I don't doubt they will enable them. But if you wish to do it now, here is the simple workaround. Everything you need to do (the Linq requires) is that the class implements IEnumerable<T>. So, I will create a generic class that wraps around any IEnumerable and implements IEnumerable<DataRow>. Here is the code:
// simple wrapper that implements IEnumerable<T>
internal class LinqList<T>: IEnumerable<T>, IEnumerable
{
IEnumerable items;
internal LinqList(IEnumerable items)
{
this.items = items;
}
#region IEnumerable<DataRow> Members
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
foreach (T item in items)
yield return item;
}
IEnumerator IEnumerable.GetEnumerator()
{
IEnumerable<T> ie = this;
return ie.GetEnumerator();
}
#endregion
}
The code is pretty straightforward, isn't it. And here is a simple test:
// create and fill table
DataTable table = new DataTable();
table.Columns.Add("Id", typeof(int));
table.Rows.Add(new object[]{1});
table.Rows.Add(new object[]{2});
table.Rows.Add(new object[]{3});
// create a wrapper around Rows
LinqList<DataRow> rows = new LinqList<DataRow>(table.Rows);
// do a simple select
IEnumerable<DataRow> selectedRows = from r in rows
where (int)r["Id"] == 2
select r;
// output result
foreach (DataRow row in selectedRows)
Console.WriteLine(row["Id"]);
It is not pretty as it could be but it certainly works. And if you want you can create your own strong typed table implementation that exposes LinqList<DataRow> Rows property. Perhaps using a code generator such as CodeSmith instead of doing boring work yourself.
|
|