- •Table of Contents
- •Preface
- •What is ASP.NET?
- •Installing the Required Software
- •Installing the Web Server
- •Installing Internet Information Services (IIS)
- •Installing Cassini
- •Installing the .NET Framework and the SDK
- •Installing the .NET Framework
- •Installing the SDK
- •Configuring the Web Server
- •Configuring IIS
- •Configuring Cassini
- •Where do I Put my Files?
- •Using localhost
- •Virtual Directories
- •Using Cassini
- •Installing SQL Server 2005 Express Edition
- •Installing SQL Server Management Studio Express
- •Installing Visual Web Developer 2005
- •Writing your First ASP.NET Page
- •Getting Help
- •Summary
- •ASP.NET Basics
- •ASP.NET Page Structure
- •Directives
- •Code Declaration Blocks
- •Comments in VB and C# Code
- •Code Render Blocks
- •ASP.NET Server Controls
- •Server-side Comments
- •Literal Text and HTML Tags
- •View State
- •Working with Directives
- •ASP.NET Languages
- •Visual Basic
- •Summary
- •VB and C# Programming Basics
- •Programming Basics
- •Control Events and Subroutines
- •Page Events
- •Variables and Variable Declaration
- •Arrays
- •Functions
- •Operators
- •Breaking Long Lines of Code
- •Conditional Logic
- •Loops
- •Object Oriented Programming Concepts
- •Objects and Classes
- •Properties
- •Methods
- •Classes
- •Constructors
- •Scope
- •Events
- •Understanding Inheritance
- •Objects In .NET
- •Namespaces
- •Using Code-behind Files
- •Summary
- •Constructing ASP.NET Web Pages
- •Web Forms
- •HTML Server Controls
- •Using the HTML Server Controls
- •Web Server Controls
- •Standard Web Server Controls
- •Label
- •Literal
- •TextBox
- •HiddenField
- •Button
- •ImageButton
- •LinkButton
- •HyperLink
- •CheckBox
- •RadioButton
- •Image
- •ImageMap
- •PlaceHolder
- •Panel
- •List Controls
- •DropDownList
- •ListBox
- •RadioButtonList
- •CheckBoxList
- •BulletedList
- •Advanced Controls
- •Calendar
- •AdRotator
- •TreeView
- •SiteMapPath
- •Menu
- •MultiView
- •Wizard
- •FileUpload
- •Web User Controls
- •Creating a Web User Control
- •Using the Web User Control
- •Master Pages
- •Using Cascading Style Sheets (CSS)
- •Types of Styles and Style Sheets
- •Style Properties
- •The CssClass Property
- •Summary
- •Building Web Applications
- •Introducing the Dorknozzle Project
- •Using Visual Web Developer
- •Meeting the Features
- •The Solution Explorer
- •The Web Forms Designer
- •The Code Editor
- •IntelliSense
- •The Toolbox
- •The Properties Window
- •Executing your Project
- •Using Visual Web Developer’s Built-in Web Server
- •Using IIS
- •Using IIS with Visual Web Developer
- •Core Web Application Features
- •Web.config
- •Global.asax
- •Using Application State
- •Working with User Sessions
- •Using the Cache Object
- •Using Cookies
- •Starting the Dorknozzle Project
- •Preparing the Sitemap
- •Using Themes, Skins, and Styles
- •Creating a New Theme Folder
- •Creating a New Style Sheet
- •Styling Web Server Controls
- •Adding a Skin
- •Applying the Theme
- •Building the Master Page
- •Using the Master Page
- •Extending Dorknozzle
- •Debugging and Error Handling
- •Debugging with Visual Web Developer
- •Other Kinds of Errors
- •Custom Errors
- •Handling Exceptions Locally
- •Summary
- •Using the Validation Controls
- •Enforcing Validation on the Server
- •Using Validation Controls
- •RequiredFieldValidator
- •CompareValidator
- •RangeValidator
- •ValidationSummary
- •RegularExpressionValidator
- •Some Useful Regular Expressions
- •CustomValidator
- •Validation Groups
- •Updating Dorknozzle
- •Summary
- •What is a Database?
- •Creating your First Database
- •Creating a New Database Using Visual Web Developer
- •Creating Database Tables
- •Data Types
- •Column Properties
- •Primary Keys
- •Creating the Employees Table
- •Creating the Remaining Tables
- •Executing SQL Scripts
- •Populating the Data Tables
- •Relational Database Design Concepts
- •Foreign Keys
- •Using Database Diagrams
- •Diagrams and Table Relationships
- •One-to-one Relationships
- •One-to-many Relationships
- •Many-to-many Relationships
- •Summary
- •Speaking SQL
- •Reading Data from a Single Table
- •Using the SELECT Statement
- •Selecting Certain Fields
- •Selecting Unique Data with DISTINCT
- •Row Filtering with WHERE
- •Selecting Ranges of Values with BETWEEN
- •Matching Patterns with LIKE
- •Using the IN Operator
- •Sorting Results Using ORDER BY
- •Limiting the Number of Results with TOP
- •Reading Data from Multiple Tables
- •Subqueries
- •Table Joins
- •Expressions and Operators
- •Transact-SQL Functions
- •Arithmetic Functions
- •String Functions
- •Date and Time Functions
- •Working with Groups of Values
- •The COUNT Function
- •Grouping Records Using GROUP BY
- •Filtering Groups Using HAVING
- •The SUM, AVG, MIN, and MAX Functions
- •Updating Existing Data
- •The INSERT Statement
- •The UPDATE Statement
- •The DELETE Statement
- •Stored Procedures
- •Summary
- •Introducing ADO.NET
- •Importing the SqlClient Namespace
- •Defining the Database Connection
- •Preparing the Command
- •Executing the Command
- •Setting up Database Authentication
- •Reading the Data
- •Using Parameters with Queries
- •Bulletproofing Data Access Code
- •Using the Repeater Control
- •More Data Binding
- •Inserting Records
- •Updating Records
- •Deleting Records
- •Using Stored Procedures
- •Summary
- •DataList Basics
- •Handling DataList Events
- •Editing DataList Items and Using Templates
- •DataList and Visual Web Developer
- •Styling the DataList
- •Summary
- •Using the GridView Control
- •Customizing the GridView Columns
- •Styling the GridView with Templates, Skins, and CSS
- •Selecting Grid Records
- •Using the DetailsView Control
- •Styling the DetailsView
- •GridView and DetailsView Events
- •Entering Edit Mode
- •Using Templates
- •Updating DetailsView Records
- •Summary
- •Advanced Data Access
- •Using Data Source Controls
- •Binding the GridView to a SqlDataSource
- •Binding the DetailsView to a SqlDataSource
- •Displaying Lists in DetailsView
- •More on SqlDataSource
- •Working with Data Sets and Data Tables
- •What is a Data Set Made From?
- •Binding DataSets to Controls
- •Implementing Paging
- •Storing Data Sets in View State
- •Implementing Sorting
- •Filtering Data
- •Updating a Database from a Modified DataSet
- •Summary
- •Security and User Authentication
- •Basic Security Guidelines
- •Securing ASP.NET 2.0 Applications
- •Working with Forms Authentication
- •Authenticating Users
- •Working with Hard-coded User Accounts
- •Configuring Forms Authentication
- •Configuring Forms Authorization
- •Storing Users in Web.config
- •Hashing Passwords
- •Logging Users Out
- •ASP.NET 2.0 Memberships and Roles
- •Creating the Membership Data Structures
- •Using your Database to Store Membership Data
- •Using the ASP.NET Web Site Configuration Tool
- •Creating Users and Roles
- •Changing Password Strength Requirements
- •Securing your Web Application
- •Using the ASP.NET Login Controls
- •Authenticating Users
- •Customizing User Display
- •Summary
- •Working with Files and Email
- •Writing and Reading Text Files
- •Setting Up Security
- •Writing Content to a Text File
- •Reading Content from a Text File
- •Accessing Directories and Directory Information
- •Working with Directory and File Paths
- •Uploading Files
- •Sending Email with ASP.NET
- •Configuring the SMTP Server
- •Sending a Test Email
- •Creating the Company Newsletter Page
- •Summary
- •The WebControl Class
- •Properties
- •Methods
- •Standard Web Controls
- •AdRotator
- •Properties
- •Events
- •BulletedList
- •Properties
- •Events
- •Button
- •Properties
- •Events
- •Calendar
- •Properties
- •Events
- •CheckBox
- •Properties
- •Events
- •CheckBoxList
- •Properties
- •Events
- •DropDownList
- •Properties
- •Events
- •FileUpload
- •Properties
- •Methods
- •HiddenField
- •Properties
- •HyperLink
- •Properties
- •Image
- •Properties
- •ImageButton
- •Properties
- •Events
- •ImageMap
- •Properties
- •Events
- •Label
- •Properties
- •LinkButton
- •Properties
- •Events
- •ListBox
- •Properties
- •Events
- •Literal
- •Properties
- •MultiView
- •Properties
- •Methods
- •Events
- •Panel
- •Properties
- •PlaceHolder
- •Properties
- •RadioButton
- •Properties
- •Events
- •RadioButtonList
- •Properties
- •Events
- •TextBox
- •Properties
- •Events
- •Properties
- •Validation Controls
- •CompareValidator
- •Properties
- •Methods
- •CustomValidator
- •Methods
- •Events
- •RangeValidator
- •Properties
- •Methods
- •RegularExpressionValidator
- •Properties
- •Methods
- •RequiredFieldValidator
- •Properties
- •Methods
- •ValidationSummary
- •Properties
- •Navigation Web Controls
- •SiteMapPath
- •Properties
- •Methods
- •Events
- •Menu
- •Properties
- •Methods
- •Events
- •TreeView
- •Properties
- •Methods
- •Events
- •HTML Server Controls
- •HtmlAnchor Control
- •Properties
- •Events
- •HtmlButton Control
- •Properties
- •Events
- •HtmlForm Control
- •Properties
- •HtmlGeneric Control
- •Properties
- •HtmlImage Control
- •Properties
- •HtmlInputButton Control
- •Properties
- •Events
- •HtmlInputCheckBox Control
- •Properties
- •Events
- •HtmlInputFile Control
- •Properties
- •HtmlInputHidden Control
- •Properties
- •HtmlInputImage Control
- •Properties
- •Events
- •HtmlInputRadioButton Control
- •Properties
- •Events
- •HtmlInputText Control
- •Properties
- •Events
- •HtmlSelect Control
- •Properties
- •Events
- •HtmlTable Control
- •Properties
- •HtmlTableCell Control
- •Properties
- •HtmlTableRow Control
- •Properties
- •HtmlTextArea Control
- •Properties
- •Events
- •Index
Implementing Sorting
that item into our local variable, dataSet. Regardless of how the DataSet is loaded, we bind it to our GridView as we did before.
If you save your work and load the Departments page in your browser, you should see that the page runs exactly as it did previously, except that now the database is accessed only once, the first time the page loads.
Implementing Sorting
To implement sorting functionality, we need to understand a few details of the inner workings of data binding.
Technically, you can’t bind a DataSet to a GridView control, because a DataSet can contain many tables, whereas the GridView control can only handle one set of rows and columns. However, by virtue of the fact that your DataSet has only contained a single DataTable, the GridView control has been smart enough to figure out that what you probably meant was the following:
Visual Basic
' Bind the grid to the DataSet
departmentsGrid.DataSource = dataSet.Tables("Departments") departmentsGrid.DataBind()
C#
// Bind the grid to the DataSet
departmentsGrid.DataSource = dataSet.Tables["Departments"]; departmentsGrid.DataBind();
However, this isn’t technically correct in the strictest sense, either. All of the GridView’s data binding is actually done through DataView objects. Thankfully, each DataTable has a DefaultView property, which the GridView will automatically use whenever you bind it to a DataTable. So, the following code listings have the same functionality as those we saw above:
Visual Basic
' Bind the grid to the DataView departmentsGrid.DataSource = _
dataSet.Tables("Departments").DefaultView departmentsGrid.DataBind()
C#
// Bind the grid to the DataView departmentsGrid.DataSource =
509
Chapter 12: Advanced Data Access
dataSet.Tables["Departments"].DefaultView;
departmentsGrid.DataBind();
DefaultView does not Apply when Binding to a DataSet
It’s interesting to note that if you bind directly to a DataSet that contains only one table, that table’s DefaultView will not be used; the GridView will generate a separate DataView itself.
DataViews represent a customized view of a DataSet for sorting, filtering, searching, editing, and navigation. When binding a GridView directly to a DataTable, the DefaultView property, which is a DataView object, is accessed automatically for us. However, if we want to enable sorting, we need to access the DataView and set its sorting parameters.
The first step to enabling sorting is to set the AllowSorting property to True. When we do that, the grid’s column headings become hyperlinks. Before we make those hyperlinks work, we need to handle the grid’s Sorting event, where we teach the grid what to do when those links are clicked.
Set the AllowSorting property of the GridView control in Departments.aspx to True, then use the designer to generate the handler for the GridView’s Sorting event. Then, complete the code as shown:
Visual Basic |
File: Departments.aspx.vb (excerpt) |
Protected Sub departmentsGrid_Sorting(ByVal sender As Object, _ ByVal e As System.Web.UI.WebControls.GridViewSortEventArgs) _ Handles departmentsGrid.Sorting
'Retrieve the name of the clicked column (sort expression) Dim sortExpression As String = e.SortExpression
'Decide and save the new sort direction
If (sortExpression = gridSortExpression) Then
If gridSortDirection = SortDirection.Ascending Then gridSortDirection = SortDirection.Descending
Else
gridSortDirection = SortDirection.Ascending End If
Else
gridSortDirection = WebControls.SortDirection.Ascending End If
'Save the new sort expression gridSortExpression = sortExpression
'Rebind the grid to its data source BindGrid()
End Sub
510
Implementing Sorting
Private Property gridSortDirection() Get
' Initial state is Ascending
If (ViewState("GridSortDirection") Is Nothing) Then
|
ViewState("GridSortDirection") = SortDirection.Ascending |
End If |
|
' |
Return the state |
Return ViewState("GridSortDirection") |
|
End |
Get |
Set(ByVal value) |
|
ViewState("GridSortDirection") = value |
|
End |
Set |
End Property |
|
Private Property gridSortExpression() |
|
Get |
|
' |
Initial sort expression is DepartmentID |
If (ViewState("GridSortExpression") Is Nothing) Then |
|
|
ViewState("GridSortExpression") = "DepartmentID" |
End If |
|
' |
Return the sort expression |
Return ViewState("GridSortExpression") |
|
End |
Get |
Set(ByVal value) |
|
ViewState("GridSortExpression") = value |
|
End |
Set |
End Property |
|
|
|
C# |
File: Departments.aspx.cs (excerpt) |
protected void departmentsGrid_Sorting(object sender, GridViewSortEventArgs e)
{
//Retrieve the name of the clicked column (sort expression) string sortExpression = e.SortExpression;
//Decide and save the new sort direction
if (sortExpression == gridSortExpression)
{
if(gridSortDirection == SortDirection.Ascending)
{
gridSortDirection = SortDirection.Descending;
}
else
{
gridSortDirection = SortDirection.Ascending;
}
}
else
511
Chapter 12: Advanced Data Access
{
gridSortDirection = SortDirection.Ascending;
}
//Save the new sort expression gridSortExpression = sortExpression;
//Rebind the grid to its data source BindGrid();
}
private SortDirection gridSortDirection
{
get
{
// Initial state is Ascending
if (ViewState["GridSortDirection"] == null)
{
ViewState["GridSortDirection"] = SortDirection.Ascending;
}
// Return the state
return (SortDirection) ViewState["GridSortDirection"];
}
set
{
ViewState["GridSortDirection"] = value;
}
}
private string gridSortExpression
{
get
{
//Initial sort expression is DepartmentID if (ViewState["GridSortExpression"] == null)
{
ViewState["GridSortExpression"] = "DepartmentID";
}
//Return the sort expression
return (string) ViewState["GridSortExpression"];
}
set
{
ViewState["GridSortExpression"] = value;
}
}
512
Implementing Sorting
Properties
We haven’t really discussed the task of defining your own properties since Chapter 4, so now might be a good time for a quick refresher. By now, you should be fairly comfortable with the idea that each of your web forms is its own class, and inherits a great deal of functionality from its parent class, Page. You’ve already dealt with quite a few of that class’s features, such as its Load event and its IsPostBack property.
You can define for your class properties that can be read-only, write-only, or are able to be read and written to. When you read data from a property, its Get code is executed. Most of the time, this code will be quite simple, but it can be as complex as you choose to make it. In the same way, when a value is written to a property, its Set code is executed, which can also be quite complex if you choose to make it so.
Finally, update the BindGrid method to apply the sorting:
Visual Basic File: Departments.aspx.vb (excerpt)
Private Sub BindGrid() ' Define data objects
Dim conn As SqlConnection Dim dataSet As New DataSet
Dim adapter As SqlDataAdapter
If ViewState("DepartmentsDataSet") Is Nothing Then
'Read the connection string from Web.config Dim connectionString As String = _
ConfigurationManager.ConnectionStrings( _ "Dorknozzle").ConnectionString
'Initialize connection
conn = New SqlConnection(connectionString) ' Create adapter
adapter = New SqlDataAdapter( _
"SELECT DepartmentID, Department FROM Departments", _ conn)
'Fill the DataSet adapter.Fill(dataSet, "Departments")
'Store the DataSet in view state ViewState("DepartmentsDataSet") = dataSet
Else
dataSet = ViewState("DepartmentsDataSet")
End If
'Prepare the sort expression using the gridSortDirection and
'gridSortExpression properties
Dim sortExpression As String
If gridSortDirection = SortDirection.Ascending Then
513
Chapter 12: Advanced Data Access
sortExpression = gridSortExpression & " ASC" Else
sortExpression = gridSortExpression & " DESC" End If
' Sort the data
|
dataSet.Tables("Departments").DefaultView.Sort = sortExpression |
|
' Bind the grid to the DataSet |
|
departmentsGrid.DataSource = _ |
|
dataSet.Tables("Departments").DefaultView |
|
departmentsGrid.DataBind() |
End Sub |
|
C# |
File: Departments.aspx.cs (excerpt) |
private void BindGrid()
{
// Define data objects SqlConnection conn;
DataSet dataSet = new DataSet(); SqlDataAdapter adapter; if(ViewState["DepartmentsDataSet"] == null)
{
//Read the connection string from Web.config string connectionString =
ConfigurationManager.ConnectionStrings[
"Dorknozzle"].ConnectionString;
//Initialize connection
conn = new SqlConnection(connectionString); // Create adapter
adapter = new SqlDataAdapter(
"SELECT DepartmentID, Department FROM Departments", conn);
//Fill the DataSet adapter.Fill(dataSet, "Departments");
//Store the DataSet in view state ViewState["DepartmentsDataSet"] = dataSet;
}
else
{
dataSet = (DataSet)ViewState["DepartmentsDataSet"];
}
//Prepare the sort expression using the gridSortDirection and
//gridSortExpression properties
string sortExpression;
if(gridSortDirection == SortDirection.Ascending)
{
sortExpression = gridSortExpression + " ASC";
514
Implementing Sorting
}
else
{
sortExpression = gridSortExpression + " DESC";
}
// Sort the data
dataSet.Tables["Departments"].DefaultView.Sort = sortExpression;
// Bind the grid to the DataSet departmentsGrid.DataSource =
dataSet.Tables["Departments"].DefaultView;
departmentsGrid.DataBind();
}
Execute the project again, and test that sorting by column works as shown in Figure 12.26.
Figure 12.26. Sorting Dorknozzle’s departments
We’ve written a lot of code here! Let’s take a look at how it works.
In order to sort the data in the grid, all we need to do is set the Sort property of the view we’re displaying to ColumnNameSortOrder, where ColumnName is, of course, the name of the column we’re sorting, and SortOrder is either ASC (for
515
Chapter 12: Advanced Data Access
ascending) or DESC (for descending). So, if you were sorting the DepartmentID column, the Sort property would need to be set to DepartmentID ASC or Department DESC.
This property must be set before the data binding is performed, as is shown in the following code, which will sort the data by DepartmentID in descending numeric order:
Visual Basic
dataTable.DefaultView.Sort = "DepartmentID DESC" departmentsGrid.DataSource = dataTable.DefaultView departmentsGrid.DataBind()
C#
dataTable.DefaultView.Sort = "Department DESC"; departmentsGrid.DataSource = dataTable.DefaultView; departmentsGrid.DataBind();
It’s a pretty simple task to sort a DataView in code like this, but if we want to let users sort the data on the basis of any column, in any direction, things get a little bit more complicated. In this case, we need to remember the previous sort method between requests.
In order to be truly user-friendly, our grid should behave like this:
The first time a column header is clicked, the grid should sort the data in ascending order, based on that column.
When the same column header is clicked multiple times, the grid should alternate between sorting the data in that column in ascending and descending modes.
When a column heading is clicked, the grid’s Sorting event is fired. In our case, the Sorting event handler (which we’ll look at in a moment) saves the details of the sort column and direction in two properties:
gridSortExpression retains the name of the column on which we’re sorting the data (such as Department)
gridSortDirection can be either SortDirection.Ascending or SortDirection.Descending
We create a sorting expression using these properties in BindGrid:
516
Implementing Sorting
Visual Basic |
File: Departments.aspx.vb (excerpt) |
'Prepare the sort expression using the gridSortDirection and
'gridSortExpression properties
Dim sortExpression |
As String |
If gridSortDirection = SortDirection.Ascending Then |
|
sortExpression = |
gridSortExpression & " ASC" |
Else |
|
sortExpression = |
gridSortExpression & " DESC" |
End If |
|
|
|
C# |
File: Departments.aspx.cs (excerpt) |
//Prepare the sort expression using the gridSortDirection and
//gridSortExpression properties
string sortExpression;
if(gridSortDirection == SortDirection.Ascending)
{
sortExpression = gridSortExpression + " ASC";
}
else
{
sortExpression = gridSortExpression + " DESC";
}
In order to implement the sorting functionality as explained above, we need to remember between client requests which column is being sorted, and whether it’s being sorted in ascending or descending order. That’s what the properties gridSortExpression and gridSortDirection do:
Visual Basic |
File: Departments.aspx.vb (excerpt) |
|
|
|
|
Private Property gridSortDirection() |
|
|
Get |
|
|
' |
Initial state is Ascending |
|
If (ViewState("GridSortDirection") Is Nothing) Then |
||
|
ViewState("GridSortDirection") = SortDirection.Ascending |
|
End If |
|
|
' |
Return the state |
|
Return ViewState("GridSortDirection") |
|
|
End |
Get |
|
Set(ByVal value) |
|
|
ViewState("GridSortDirection") = value |
|
|
End |
Set |
|
End Property |
|
|
Private Property gridSortExpression() |
|
|
Get |
|
|
' |
Initial sort expression is DepartmentID |
|
|
|
|
517
Chapter 12: Advanced Data Access
If (ViewState("GridSortExpression") Is Nothing) Then ViewState("GridSortExpression") = "DepartmentID"
End If
' Return the sort expression
Return ViewState("GridSortExpression")
End Get |
|
Set(ByVal value) |
|
ViewState("GridSortExpression") = value |
|
End Set |
|
End Property |
|
C# |
File: Departments.aspx.cs (excerpt) |
private SortDirection gridSortDirection
{
get
{
// Initial state is Ascending
if (ViewState["GridSortDirection"] == null)
{
ViewState["GridSortDirection"] = SortDirection.Ascending;
}
// Return the state
return (SortDirection) ViewState["GridSortDirection"];
}
set
{
ViewState["GridSortDirection"] = value;
}
}
private string gridSortExpression
{
get
{
//Initial sort expression is DepartmentID if (ViewState["GridSortExpression"] == null)
{
ViewState["GridSortExpression"] = "DepartmentID";
}
//Return the sort expression
return (string) ViewState["GridSortExpression"];
}
set
{
ViewState["GridSortExpression"] = value;
}
}
518
Implementing Sorting
Here, we use the ViewState collection to store information about which column is being sorted, and the direction in which it’s being sorted.
When the Sorting event handler fires, we set the gridSortExpression and gridSortDirection properties. The method starts by retrieving the name of the clicked column:
Visual Basic File: Departments.aspx.vb (excerpt)
Protected Sub departmentsGrid_Sorting(ByVal sender As Object, _
ByVal e |
As System.Web.UI.WebControls.GridViewSortEventArgs) _ |
Handles |
departmentsGrid.Sorting |
' Retrieve the name of the clicked column (sort expression) |
|
Dim sortExpression As String = e.SortExpression |
|
|
|
C# |
File: Departments.aspx.cs (excerpt) |
protected void departmentsGrid_Sorting(object sender, GridViewSortEventArgs e)
{
// Retrieve the name of the clicked column (sort expression) string sortExpression = e.SortExpression;
Next, we check whether the previously-clicked column is the same as the newlyclicked column. If it is, we need to toggle the sorting direction. Otherwise, we set the sort direction to ascending:
Visual Basic File: Departments.aspx.vb (excerpt)
' Decide and save the new sort direction
If (sortExpression = gridSortExpression) Then
If gridSortDirection = SortDirection.Ascending Then
gridSortDirection |
= SortDirection.Descending |
Else |
|
gridSortDirection |
= SortDirection.Ascending |
End If |
|
Else |
|
gridSortDirection = |
WebControls.SortDirection.Ascending |
End If |
|
|
|
C# |
File: Departments.aspx.cs (excerpt) |
// Decide and save the new sort direction if (sortExpression == gridSortExpression)
{
if(gridSortDirection == SortDirection.Ascending)
{
gridSortDirection = SortDirection.Descending;
}
519