advanced web development using c# david figge [email protected] session 1 last update: 1/12page...
TRANSCRIPT
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Web Development using C#
David [email protected]
Session 1
Last Update: 1/12 Page 1
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Web Development using C#
Welcome
Last Update: 1/12 Page 2
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Web Development using C#
This is the 2nd in a 3 part series designed to introduce you to Web Development using C# and ASP.Net Class 1 introduced you to the basics of Web
development using ASP and C#, just finishing off with things like Data Binding
In Class 2 we will delve into several specialized controls, play a bit with File Streams and LINQ, work with CSS, and finish up with a brief tutorial in deploying your site.
In Class 3 you complete the picture with security, web services, and some Ajax.
Last Update: 1/12 Page 3
Copyright (C) 2012 by David Figge. All Rights Reserved.
Class Format
This class is designed around the lecture/lab format
We will discuss a subject in class in detail, Then YOU will experience that subject with one or
more labs Feel free to ask questions any time
Even stupid ones, like “How is Ajax different than SOAP?
It’s critical that you understand as we encounter the material, because we build on this knowledge
If it’s appropriate to defer the question until later, I will Questions between sessions?
Contact me at [email protected] I’ll try to get back to you in a timely manner
Last Update: 1/12 Page 4
Copyright (C) 2012 by David Figge. All Rights Reserved.
Slides
Over the years, I’ve found that the best system for me is to have a series of PowerPoint slides “lead” our discussion This allows me to present the material in an
organized way I also make these slides available to you
This way, you can use them for notes or for a reference in the future
Because they're used as a reference, I try to make sure they're complete This may make them 'busier' than many slide
presentations, but I think it's worth it
I also like to make use of these “speech bubbles”. They help me make a point without losing the focus of the slide.
Don’t let these throw you off.So when you use the slides, remember to ‘run’ the presentation (“View Slide Show”) in order to make the bubbles
move out of the way until appropriate.
Last Update: 1/12 Page 5
Copyright (C) 2012 by David Figge. All Rights Reserved.
Facility Basics
Restrooms, etc. I usually try to take a 15 minute
break every hour or so If you feel I've gone "too long", let me
know.
Last Update: 1/12 Page 6
Copyright (C) 2012 by David Figge. All Rights Reserved.
Environment Basics
You should assume that all data will be wiped off
the disk between sessions
It may not be, but don’t take chances
You can also copy it to a USB drive or email to
yourself
Or you can save it to the network
Last Update: 1/12 Page 7
Copyright (C) 2012 by David Figge. All Rights Reserved.
People Basics
Mostly for my benefit Let’s introduce ourselves with
Your name What you do Any courses you’ve taken here before Why you are taking this course Are there any specific things you were hoping to
learn What do you like to do in your spare time?
Last Update: 1/12 Page 8
Copyright (C) 2012 by David Figge. All Rights Reserved.
Questions
Questions before we go forth?
Last Update: 1/12 Page 9
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Web Development using C#
Course Overview
Last Update: 1/12 Page 10
Copyright (C) 2012 by David Figge. All Rights Reserved.
Class 2: Course Objectives
Understand of the Philosophy of the C# Language
Utilize Structured Methodology in Constructing C# Modules
Create, Compile, Debug ASP.Net programs using C# elements
Variables, functions, arrays, classes, .Net framework elements
Understand how to use the core controls including GridView and
ListView
Understand how to create your own custom User Controls
Understand the basics of Caching, File Streams, and XML
Understand how to use LINQ in web applications
Understand how to use Cascading Style Sheets and Themes to
provide a consistent look and feel to your site
Understand the basics of deploying a Web Site
Last Update: 1/12 Page 11
Copyright (C) 2012 by David Figge. All Rights Reserved.
Session 1: Introductions, Overview Gridviews Controls
Session 2: More on GridView Controls
Session 3: GridView Once Again ListViews
Session 4: The DetailsView and
FormView Caching
Session 5: File Streams Using XML
Session 6: User Controls
Session 7: CSS and Themes
Session 8: LINQ
Linq with DataSets Linq with Entities
Session 9: Deployment
Session 10: Final Lab
Class 2 Schedule
Last Update: 1/12 Page 12
Copyright (C) 2012 by David Figge. All Rights Reserved.
Text is Pro ASP.NET 4 in C# 2010
Matthew MacDonald, et. Al. I chose this because:
Good text Reasonable to read Great reference book to
have in the future My exercises are typically not
directly from the book This way you can have more exercises available to you Use it as a source to augment my lectures
Our discussions will be chapters 10-18 If you can’t find associated reading, let me know
Course Textbook
Questions before we get started?
Last Update: 1/12 Page 13
Copyright (C) 2012 by David Figge. All Rights Reserved.
Starting Project
Let’s Get Started…
Last Update: 1/12 Page 14
Copyright (C) 2012 by David Figge. All Rights Reserved.
Starting Project
We’re going to start by creating a base project on which to build and experiment Further, it can act as a good “review”
We’re going to build program called “Reservations” to keep track of table reservations for a restaurant We’ll be building on this project throughout the
classes Not surprisingly, the Web app will be driven
from a database Which is a reasonable place to start
The database that supports this program will look like this...
Last Update: 1/12 Page 15
Copyright (C) 2012 by David Figge. All Rights Reserved.
Reservations Database
Customers Table
CustomerID* Integer Unique ID for customer
LastName String Customer’s Last Name
FirstName String Customer’s First Name
Address String Customer’s street address
City String Customer’s city
State String[2] Customer’s State
Zip String[9] Customer’s Zip
Phone String[14] Customer’s Phone
Email String Customer’s Email
Last Update: 1/12 Page 16
DiningTable Table
TableID* Integer Unique ID for dining table
Capacity Integer Seats at the table
DiningReservation Table
ReservationID* Integer Unique ID for reservation
CustomerID Integer Customer’s ID
TableID Integer Table’s ID
StartTime DateTime Reservation Start Time
EndTime DateTime Reservation End Time
Guests Integer Number of Guests
FK: Customers Table
FK: DiningTable Table
*Unique Identifier: Indentity, Auto-Increment
We’ll build our base Web Site, and use VS to create our database. Then we’ll display data in our Web Page…
Ready?
The table reservations portion of the program will be driven by a table
called DiningReservation.
ReservationID is a unique identifier for
each row in the table. All tables
should have a way to uniquely identify
each row. This is the Primary Key, and is maintained by SQL
Server.
Two key pieces of information
for a reservation
are the customer and
the table assigned to them. These
are both references to rows in other
tables.
We also need to know when the customer will arrive,
depart (assume 90 minutes to eat), and the total number of
guests.
The CustomerID is a link to a row in the Customers table, which keeps
information about each customer of the restaurant.
And the TableID is a link to a DiningTable row, which keeps track of the table ID and the number of seats
at the table.
When you have one table have a reference to a row in another table, the best way to do that is through a
Foreign Key relationship. We will establish one for both the
CustomerTable-DiningReservation, and the DiningTable-
DiningReservation relationships.
Copyright (C) 2012 by David Figge. All Rights Reserved.
Reservations Database
Steps to Creating the Reservations Database
1. Create the Base Web Site1. File/New Project/Web/New ASP.Net Web
Application, named Reservations
2. Open Server Explorer from the View Menu
1. Create new SQL Server Database2. Call it Reservations3. Create the tables as shown here…
Last Update: 1/12 Page 17
Copyright (C) 2012 by David Figge. All Rights Reserved.
Establish the foreign key relationships DiningReservation-Customers and DiningReservation-DiningTable.
When you’re ready, we'll add some data…
Reservations Database
Customers Table
CustomerID Integer No nulls, Identity, Auto-Increment, Primary Key
LastName nvarchar(50) No Nulls
FirstName nvarchar(50)
Address nvarchar(50)
City nvarchar(50)
State nchar(2)
Zip nchar(10)
Phone nchar(14)
Email nvarchar(50)
Last Update: 1/12 Page 18
DiningTable Table
TableID Integer No nulls, Identity, Auto-Increment, Primary Key
Capacity Integer No Nulls
DiningReservation Table
ReservationID Integer No nulls, Identity, Auto-Increment, Primary Key
CustomerID Integer No Nulls
TableID Integer No Nulls
StartTime DateTime No Nulls
EndTime DateTime No Nulls
Guests Integer No Nulls
Copyright (C) 2012 by David Figge. All Rights Reserved.
Reservations Database
Some Data… Add Customer Names
Use “Show Table Data” from the table in Server Explorer. Add the names: Amanda Jones, Byron Barnes, Carl
Moore, Chris Johnston, Jay Carlton, Sam Preston, Sarah Smith, Wendy Walters
Just add the names for now. We’ll add the other data later
Add DiningTable Data Add 20 tables with various capacities from 2-10
Add Reservations Data Add 3 for now (we’ll add more later). Make sure the
capacity of the table (in blue) you give them supports the number of guests (in purple).
1,1, 7:30 PM, 9:00 PM, 4 (today’s date is fine) 2, 2, 6:30 PM, 8:00 PM, 6 3, 4, 6:30 PM, 8:00 PM, 4
Last Update: 1/12 Page 19
Copyright (C) 2012 by David Figge. All Rights Reserved.
Our First Page
Let’s create apage to displaythe reservationdata we justentered.
In Site.Master,change theheader to read “Restaurant Reservation System”
We’ll start with a GridView to show the basic reservation information
So go back to Default.aspx (design mode) and drag a GridView control from the toolbox onto it
Last Update: 1/12 Page 20
Copyright (C) 2012 by David Figge. All Rights Reserved.
Setting the Data Source
Last Update: 1/12
Click on the Smart Tab (“>”) and where it says Choose Data Source, select: <New Data Source> SQL Database (called ReservationData) Create a new connection to the
Reservations database The SQL statement should come out as
“SELECT * FROM [DiningReservation] ORDER BY [StartTime]”
When you run the program, you should see data in the GridView
Page 21
Copyright (C) 2012 by David Figge. All Rights Reserved.
But It’s Not Pretty…
So it’s not very professional right out of the box, is it?
So let’s set some elements to make things look better
To begin with, let’s set some of the column headings and format of the displays
Go to the “Source” mode of the Default.aspx file and we’ll fix some of these things in code Let’s look at this…
Last Update: 1/12 Page 22
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example Default.aspx Columns
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False” DataKeyNames="ReservationID“ DataSourceID="ReservationData"> <Columns> <asp:BoundField DataField="ReservationID" HeaderText="ReservationID" InsertVisible="False" ReadOnly="True" SortExpression="ReservationID" /> <asp:BoundField DataField="CustomerID" HeaderText="CustomerID" SortExpression="CustomerID" /> <asp:BoundField DataField="TableID" HeaderText="TableID" SortExpression="TableID" /> <asp:BoundField DataField="StartTime“ HeaderText="StartTime" SortExpression="StartTime" /> <asp:BoundField DataField="EndTime" HeaderText="EndTime“ SortExpression="EndTime" /> <asp:BoundField DataField="Guests" HeaderText="Guests“ SortExpression="Guests" /> </Columns></asp:GridView>
Last Update: 1/12 Page 23
Locate this section in the source code. As you can see, this defines the GridView control we're using.
This section defines the individual columns within the GridView. That's what's not quite looking good yet…
As you can see, there's one BoundField element defined for each row. That's where we can customize
how things look…
So modify this section of code so it looks like this next page…
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example Default.aspx Columns Revisited
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ReservationID" DataSourceID="ReservationData"> <Columns> <asp:BoundField DataField="ReservationID" HeaderText="Reservation Number" InsertVisible="False" ReadOnly="True" SortExpression="ReservationID" /> <asp:BoundField DataField="CustomerID" HeaderText="Customer Number" SortExpression="CustomerID" /> <asp:BoundField DataField="TableID" HeaderText="Table Number" SortExpression="TableID" /> <asp:BoundField DataField="StartTime" HeaderText="Arrive" DataFormatString="{0:t}" SortExpression="StartTime" /> <asp:BoundField DataField="EndTime" HeaderText="Depart" DataFormatString="{0:t}" SortExpression="EndTime" /> <asp:BoundField DataField="Guests" HeaderText="Guests" SortExpression="Guests" /> </Columns></asp:GridView>
Last Update: 1/12 Page 24
Everything in gray is already there and doesn't need to change. Black sections are ones that change, red
indicates the actual change itself… It should run (and look better!)
So it's looking much better now! Before we go on, I don't want to gloss
over this very important DataFormatString property. Let's take
a closer look at that…
Copyright (C) 2012 by David Figge. All Rights Reserved.
DataFormatString
The DataFormatString is used to format the data in a form that is more appropriate for the data you're displaying In our case, displaying the full date and
time was too much data. The {0:t} says "Display a short version of the time"
There are many options in the format string. Let's look at a few of them…
Last Update: 1/12 Page 25
Copyright (C) 2012 by David Figge. All Rights Reserved.
DataFormatString Options
Last Update: 1/12 Page 26
Type Format String Description/Example
Currency {0:C} $1,234.56
Scientific Notation {0:E} 1.23456E+003
Percentage {0:P} 53%
Decimal {0:F2} 45.23 (# is decimal places)
Short Date {0:d} 7/4/1776
Long Date {0:D} Thursday, July 4, 1776
Time {0:T} 10:00:00 AM
Short Time {0:t} 10:00 AM
This is a (very) short portion of a very long list. Check inhelp for many more options…
Copyright (C) 2012 by David Figge. All Rights Reserved.
Reservations Gridview
So now we're getting closer Now let's format the ID and Guest columns so that they're
centered in the column Many of properties that you set in code can also be done
via the Properties window in the "Design" mode So let's go back to the Design mode, click on the GridView,
and make sure that the Properties window is displayed. Note that the properties we set in code are reflected in the
properties window Now let's center the ID and Guest columns
Select Columns from the property window, press … Now select the column to change and find the ItemStyle
Open it up, and change the HorizontalAlign to Center.
Do this for the Reservation Number, Customer Number, Table Number, and Guests columns
Look in the source code to see how it changed when you set these properties…
Last Update: 1/12 Page 27
Copyright (C) 2012 by David Figge. All Rights Reserved.
A Better SQL Statement
It's looking better, but still isn't where a professional product should be
We don't want customer IDs and separate columns for first and last. Let's fix that.
From the Design window, click on the SqlDataSource and click on the Task Menu tab
Hit NEXT, then tell it we want to specify a custom SQL statement
This allows us the flexibility to mix, match, and combine our data via SQL
The table just reflects the resulting SQL Table from the SQL query
Hit NEXT. Here's the custom SQL Statement:
Last Update: 1/12 Page 28
Copyright (C) 2012 by David Figge. All Rights Reserved.
A Better SQL Statement
SELECT DR.ReservationID, DR.CustomerID, DR.TableID, DR.StartTime, DR.EndTime, DR.Guests, CUST.LastName, CUST.FirstName, DT.Capacity, CUST.LastName + ', ' + CUST.FirstName AS FullnameFROM DiningTable AS DT INNER JOIN DiningReservation AS DR INNER JOIN Customers AS CUST ON DR.CustomerID = CUST.CustomerID ON DT.TableID = DR.TableIDORDER BY DR.StartTime
Copy and Paste should work, but let's talk about the statement… When asked if you want the system to regenerate the table, say
YES. I think you'll agree that we've made an improvement…
Last Update: 1/12 Page 29
Copyright (C) 2012 by David Figge. All Rights Reserved.
Time to Play A Bit…
Last Update: 1/12
Your turn. Make thetable look as it does here
I added a few morenames for realism
You do that, too… Notes:
Start by removingunwanted columns
This can all be done viathe Columns property or via code (your choice)
All fields are centered except Customer Name Be sure to change the header text of the columns The Customer Name field is a field created by the SQL statement
called FullName Header text is set by the control's HeaderStyle property Alternating colors is set by the control's AlternatingRowStyle
property.
Page 30
40 Minutes
Copyright (C) 2012 by David Figge. All Rights Reserved.
Auto Formatting
Last Update: 1/12
All right. We're looking pretty good here.
As you can probably see, formatting the visuals for lots of tables could be a bit of a bother
You can also use the Auto Formatting function from the "Smart Tag" (aka task menu)
Let's see how that works If you like yours as it is, just watch me…
Page 31
Copyright (C) 2012 by David Figge. All Rights Reserved.
Who's There?
Last Update: 1/12
What we have is a prettygood system for showinghow things are for the day.
What we need is a systemthat changes as peoplearrive.
To do that, we need tokeep track of whethera party has arrived or not.
To implement this: Add a field HasArrived to the DiningReservation table (make it a 'bit'
data type, which holds True or False) Initialize the new field in the records, setting the first record to TRUE
(so we have one party that has arrived), the rest to FALSE Add the new column to the SQL statement request Add the column tothe GridView display so it shows like this example.
Page 32
20 Minutes
Copyright (C) 2012 by David Figge. All Rights Reserved.
More Formatting…
We'll get to changing the record when the party arrives in just a few minutes
But first, let's look at another formatting option This one allows you to change the
formatting of one row based on the data displayed
In our case, to allow us to visually change rows where people have arrived
We'll de-emphasize the row. The data should still be shown, but it's not nearly as important as people who haven't arrived.
Last Update: 1/12 Page 33
Copyright (C) 2012 by David Figge. All Rights Reserved.
Data-driven Formatting
To do this, we'll add a handler to the RowDataBound event of the GridView This event is triggered as each row is being
drawn up During this event, you have access to the
data being displayed – in our case the HasArrived flag
So we'll look to see if that flag is true, and if it is, we'll change the default formatting of the row.
Start by adding the RowDataBound Handler In the method, put this code…
Last Update: 1/12 Page 34
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example The RowDataBound Handler
protected void GridView1_RowDataBound(...){ if (e.Row.RowType == DataControlRowType.DataRow) { if ((bool)DataBinder.Eval(e.Row.DataItem, "HasArrived") == true) { e.Row.BackColor = System.Drawing.Color.LightGray; e.Row.ForeColor = System.Drawing.Color.DarkGray; } }}
Last Update: 1/12 Page 35
Notice the text in Gray. That's already been added by Visual Studio. It's just here to show you where the code goes. Also, the … shows
that there's more code on the line, but it's not important to what we're doing. When it's all
in, it should run.
Here's where we look at the "HasArrived" data column. If it's true (they've arrived)…
Then we change the row's background color to light gray, and the foreground color (the text) to dark gray. Still readable, but not as obvious
as people who haven't arrived.
Notice how we access the data for the row. We call the DataBinder.Eval method, passing in
e.Row.DataItem (essentially the record), asking for the HasArrived field in it.
Also notice this line. Because not all rows contain data (like the header row), we need to be careful only to request data from a row that actually HAS data! That's what this line does.
Does this allmake sense?
Type it in, then we’ll look at it…
Copyright (C) 2012 by David Figge. All Rights Reserved.
Row Selection
Okay. Now that we have the grid responding properly when someone has arrived, let's add the ability to change that setting from the GridView.
To do this, we're going to start by adding a column to the GridView with a "Here!" button (one for each row)
From the Design mode, highlight the GridView and open the Columns settings from the Properties window
In the top window, open the CommandField branch and select the item that says "Select"
Add it to the displayed columns by clicking the Add button. Move it to the top of the list.
From the bottom window, highlight the new element and change the SelectText to read "Here!"
Give it a try (run it)!
Last Update: 1/12 Page 36
Copyright (C) 2012 by David Figge. All Rights Reserved.
Row Selection
Okay, not much happens yet Although the row did "highlight"
Not much happened because we don't have any code to cause those changes to occur.
When you press the Here button, it selects the row.
When you select a row, several things occur: SelectedIndexChanging is fired
You can catch this and cancel the row change if needed (set the e.Cancel flag to true and return)
The SelectedIndex property is set to the new row The SelectedIndexChanged event is fired
This is where you can trap the event and update the database based on the button click. Let's do that
Add a SelectedIndexChanged handler via Properties, then…
Last Update: 1/12 Page 37
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example SelectedIndexChanged
protected void GridView1_SelectedIndexChanged(...){ int thisRow = GridView1.SelectedIndex; int ReservationID = (int)GridView1.SelectedDataKey.Value; SqlConnection connection = new SqlConnection(ReservationData.ConnectionString); connection.Open(); string newValue = "true"; SqlCommand cmd = new SqlCommand("UPDATE [DiningReservation] SET [HasArrived] = '" + newValue + "' WHERE [ReservationID] = " + ReservationID.ToString(),connection); cmd.ExecuteNonQuery(); Refresh();} void Refresh(){ Response.Redirect("Default.aspx");}
Last Update: 1/12 Page 38
There are two key fields in the GridView we need here. First, the DataKeyNames must be set. This
defines the primary key for the database table. In our case, it's the ReservationID (since the data comes from that table, the DataSource sets this for us).
The second key element is the SelectedDataKey. It's the primary key (via DataKeyNames) for the currently selected row. So, in our case, it's the
ReservationID of the row we just selected.
Based on that key, we can now set the HasArrived field to 'true' for the selected row. We'll do that
through a standard SQL statement. Here we create a SQLConnection object, using the connection string
that's in ReservationData.
Then we need to trigger a redraw of the GridView. Since we'll need that several places, we'll create a method to
do that called Refresh()
Have I lostanyone?
Once again, type it in, then we'll talk about it…
Then we create our SQL statement (setting HasArrived to 'true') for our
this record.
Then we execute the statement.
…which simply causes our page to redraw itself.
Copyright (C) 2012 by David Figge. All Rights Reserved.
Lookin' Better!
Alright. Now we're looking a bit better.
Before we go any further, I want to give you a chance to play a bit with what we've learned up to now.
So…
Last Update: 1/12 Page 39
Copyright (C) 2012 by David Figge. All Rights Reserved.
The Customer Screen
Last Update: 1/12
Add a second screen, linked to by the home page, that Uses a GridView to display the contents of
the Customers table Don't display the Customer ID
But that should be the DataKeyNames parameter so we can use it when we add editing
Remember there isn't much data in there yet, but have it display all the columns anyway.
Extra – Add a column to the grid that indicates whether the customer currently has a reservation in the system.
Page 40
40 Minutes
Copyright (C) 2012 by David Figge. All Rights Reserved.
Row Selection Revisited
Let's revisit our Table Reservations page Let's turn the "little too obvious" button into something
more subtle: a link You can use any data field as a link also, and that's how
we'll implement this Start by adding a ButtonField
Set the ButtonType to Link Set the HeaderText to ID Set the CommandName to Select
This causes the row to be selected, thus invoking the SelectedIndexChanged event where our code is
Set the DataTextField to ReservationID This tells the system to use this row as the data (so we click on the
record ID to select the row). Note that we're still setting the record in the row to "Arrived",
like the buttons. Just another way of selecting rows. Once it's working, we can remove the button-based
column
Last Update: 1/12 Page 41
Copyright (C) 2012 by David Figge. All Rights Reserved.
Toggling the Selection
Okay, I admit that it's getting a little annoying that we only set the customer record to "Arrived"
Let's change the link processing so it's a toggle instead It changes it's True/False state back and
forth every time you select it. To do that, we just have to get the
existing state of the record field and select its opposite… Here's the code changes…
Last Update: 1/12 Page 42
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example SelectedIndexChanged
protected void GridView1_SelectedIndexChanged(...){
int thisRow = GridView1.SelectedIndex; int ReservationID = (int)GridView1.SelectedDataKey.Value; SqlConnection connection = new
SqlConnection(ReservationData.ConnectionString); connection.Open(); string newValue = "true"; SqlCommand cmd = new SqlCommand("SELECT HasArrived FROM " + "[DiningReservation] WHERE [ReservationID] = " + ReservationID.ToString(),connection); bool result = (bool)cmd.ExecuteScalar(); if (result == true) newValue = "false"; cmd = new SqlCommand("UPDATE [DiningReservation] SET [HasArrived] = '" + newValue + "' WHERE [ReservationID] = " +
ReservationID.ToString(),connection); cmd.ExecuteNonQuery(); Refresh();}
Last Update: 1/12 Page 43
The rest of the code already sets the table column to whatever newValue is, so there's no need to change
anything else…
We originally set the newValue to true. Now we look to see if we should really be setting
it to false (e.g. if the 'HasArrived' value already says true).
A pretty direct way to determine the current setting of the HasArrived flag is to ask the
database. So here we create a SQL statement that does that.
Because we're looking for a single return value, we can use ExecuteScalar, casting the results to bool.
Any questionson this?
You know the drill… Type first, then talk…
Copyright (C) 2012 by David Figge. All Rights Reserved.
Simple Editing
We're looking pretty good now, but an obvious thing to add is the ability to edit a record.
This is actually pretty easy Enable Editing within the GridView Provide an SQL statement as an Update
Command in the SqlDataSource. Let's try that…
Last Update: 1/12 Page 44
Copyright (C) 2012 by David Figge. All Rights Reserved.
Simple Editing
Last Update: 1/12
Using the GridView's "Smart Tab", turn on Enable Editing
This turns on a link saying Edit. Let's move that to a more appropriate location
Put it to the right of Guests, and put "Change" as the column heading
Use the "Configure Data Source" option from the DataSource object to set the Update Command field to:
UPDATE DiningReservationSET TableID =@TableID, StartTime =@StartTime,EndTime =@EndTime, Guests =@GuestsWHERE ReservationID=@ReservationID
You should be able to edit at this point. Give it a try…
Page 45
By making the parameter name be the same as the SQL Column name, the parameter for that column is
automatically created. Nice, huh?
Copyright (C) 2012 by David Figge. All Rights Reserved.
Using Templates
We've been able to control the look and feel of a GridView pretty well with the basic formatting functions it has built in
However, we unleash another level of options when we use GridView Templates.
By inserting a Template Field as a column, you have the full control of the underlying HTML to determine the look, feel, and function of the field
Let's look at simple example Add a column to the right end of your GridView using
the TemplateField type, making the HeaderText be "Summary"
Go into the source mode, and find the last column and insert this code…
Last Update: 1/12 Page 46
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example The Summary Column
<asp:TemplateField HeaderText="Summary"> <ItemTemplate> <%# Eval("FirstName") %> <%# Eval("LastName") %> will arrive at <%# Eval("StartTime") %> with <%# Eval("Guests") %> guests. </ItemTemplate></asp:TemplateField>
Last Update: 1/12 Page 47
Recall that the <%# … %> tag indicates that we're using
Data Binding.
In the Binding Tag we use the static function Eval(), which gives us the
value of the database column for the current record.So we're combining the first name, last
name, start time, and guests to create an HTML text line, all within a GridView
column. Templates provide us with options that are almost limitless.
Once you get it in, we'll discuss it…
Copyright (C) 2012 by David Figge. All Rights Reserved.
Checking the Arrival
Last Update: 1/12
As an example of what we can do, let's take the first two columns of our GridView (the record ID and the "Arrived" status) and replace them with a simple checkbox. Templates allow us to insert controls into
columns! Then we'll trap the CheckChanged event
and use it to toggle the arrival status Similar to how we did it when we selected the
row Ready?
Page 48
Copyright (C) 2012 by David Figge. All Rights Reserved.
Adding the CheckBox
Last Update: 1/12
Start by removing the first two columns Add a TemplateField as the first column
Make the HeadingText be "Arrived" and the positioning centered
Using the "smart tag", select "Edit Templates" Our new column should be at the top of the list
and currently displayed Drag a CheckBox from the toolbox onto it
Pretty easy to add controls, huh? Now go into the Source mode and enter this ASP
code…
Page 49
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example Adding the CheckBox
<asp:TemplateField HeaderText="Arrived"> <ItemTemplate> <asp:CheckBox ID="CheckBox1" runat="server" AutoPostBack = "true" OnCheckedChanged="ArrivedCheckChanged" Checked='<%# Eval("HasArrived") %>' Text="Arrived" /> </ItemTemplate> <ItemStyle HorizontalAlign="Center" /></asp:TemplateField>
Last Update: 1/12 Page 50Once you get it in, we'll discuss it…
Here we're saying to set the checkmark based on the record's HasArrived field,
and when the check mark changes, to call the method ArrivedCheckChanged.
Let's look at that function now…
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example Adding the CheckBox
public void ArrivedCheckChanged(object sender, EventArgs e){ CheckBox cb = (CheckBox)sender; GridViewRow row = (GridViewRow)cb.NamingContainer; int GridViewRowNum = row.DataItemIndex; int ReservationID = (int)GridView1.DataKeys[GridViewRowNum].Value; string newValue = "true"; if (cb.Checked == false) newValue = "false"; SqlConnection connection = new SqlConnection(ReservationData.ConnectionString); connection.Open(); SqlCommand cmd = new SqlCommand("UPDATE [DiningReservation] SET [HasArrived] = '" +
newValue + "' WHERE [ReservationID] = " + ReservationID.ToString(), connection); cmd.ExecuteNonQuery(); Refresh();}
Last Update: 1/12 Page 51Go ahead and get it typed in before we talk…
So there's a lot going on here. Let's break it down…
Every event gets two parameters: the triggering object and EventArgs
Here we take the triggering object (the checkbox) and store it into a variable cb. This gives us the checkbox object that was clicked by the user.The control's NamingContainer property gives you the
row where it sits within the GridView.Now we get the index (row number) of the row. With that information…
We can get the database row's primary key (which is what we
need to update the table).Now it becomes a simple matter (similar to how
we did it in SelectedIndexChanged) to update the table row based on the checkmark's on/off status.
Questions on what we've done here?
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Editing
As you know, we can now edit a record from the GridView However, it's pretty limited editing
Text boxes aren't always the best way to edit For example, our Table # can't just take any value A Drop-Down list box would be more appropriate
No validation It often looks amateurish
Like, well, you just turned editing on with the GridView
Now that we know about Templates, we have the skills to use more advanced editing tools…
Last Update: 1/12 Page 52
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Editing
So to see how this works, let's put the Table Number field into a Drop-Down List Box (e.g. Combo box)
We will do this by1. Using templates in the ASP file to
display the box, fill it, and set the right value for the record, and store it to the database when the value changes
2. Add the functions to the code-behind page to support this
Last Update: 1/12 Page 53
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example Advanced Editing: ASP
<asp:BoundField DataField="Fullname" HeaderText="Customer Name" ReadOnly="True"
SortExpression="Fullname"> <ItemStyle Font-Bold="True" /></asp:BoundField><asp:TemplateField HeaderText="Table #"> <ItemTemplate> <asp:DropDownList runat="server" ID="TableNum" AutoPostBack = "true" SelectedIndex='<%# GetTableIndex(Eval("TableID")) %>' DataSource='<%# TableNumbers %>' OnSelectedIndexChanged="TableSelectionChanged" /> </ItemTemplate> </asp:TemplateField> <asp:BoundField DataField="Capacity" HeaderText="Table Size" SortExpression="Capacity">
Last Update: 1/12 Page 54
Replace the existing BoundField entry for the TableID with this code (it won't work yet)…
Here we use the TemplateField tag, setting the header textNow we have a template
specific to this item.So we're using a
DropDownList with an ID of TableNumThis causes events to trigger
when the item is changed
Identifying the index value within the drop down of the table number in the record is a
bit complex. We'll do that in the Code Behind page. This is how we 'call' the
function there, passing the TableIDWe'll do the same to get the
appropriate table numbers, only this time we're using a property.
Finally, we're saying "When the selection changes, call this function in the Code
Behind page" which will update the database record and refresh the display.
Questions so far…?
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example Advanced Editing: CS Part 1
protected string[] TableNumbers{ get { SqlConnection connection = new SqlConnection(ReservationData.ConnectionString); connection.Open(); SqlCommand cmd = new SqlCommand("SELECT TableID FROM DiningTable",connection); SqlDataReader tableList = cmd.ExecuteReader(); List<String> tables = new List<String>(); while (tableList.Read()) { tables.Add(tableList["TableID"].ToString()); } return tables.ToArray(); }}protected int GetTableIndex(object tableNumber){ return Array.IndexOf(this.TableNumbers, tableNumber.ToString());}
Last Update: 1/12 Page 55Add this code to your Code Behind page…
The TableNumbers method returns an array of legal table numbers. We grab
this from the database.
We start by executing (in a way that should be familiar now) a SQL Request.
Because we need multiple values back, we use a DataReader objectWe create an empty List object, then
use the reader to fill it with the contents of each data row returned
Finally, we return the list object values converted to an array.
Questions on this property before we move on?
The GetTableIndex returns the location within the array of tableIDs where the passed-in tableID is located. This
makes it display the right value when the box is displayed.The Array.IndexOf searches through the array, returning the index of the specified object (which is what we need). Make sense?
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example Advanced Editing: CS Part 2
public void TableSelectionChanged(object sender, EventArgs e){ DropDownList ddl = (DropDownList)sender; GridViewRow row = (GridViewRow)ddl.NamingContainer; int GridViewRowNum = row.DataItemIndex; int ReservationID =
(int)GridView1.DataKeys[GridViewRowNum].Value; SqlConnection connection = new SqlConnection(ReservationData.ConnectionString); connection.Open(); SqlCommand cmd = new SqlCommand("UPDATE [DiningReservation] "+ "SET [TableID] = '" + ddl.SelectedValue + "' WHERE " + "[ReservationID] = " + ReservationID.ToString(), connection); cmd.ExecuteNonQuery(); Refresh();}
Last Update: 1/12 Page 56Add this code to your Code Behind page too…
So this method is called when the user changes the value in the drop-down box.
Like we did with the checkbox, here we're getting the ReservationID based
on the row that the list box is in…
Then we create a new SQL statement that updates the DiningReservation
table to use the selected table.
Finally, we call our Refresh method to redisplay the updated database values.
Copyright (C) 2012 by David Figge. All Rights Reserved.
Exercise
Last Update: 1/12
Use a DropDownList to display the Arrival times of the customers (so they can be changed if they're late) Arrival times are on the ½ hour, from 5:00
PM to 10:00 PM When changed, modify the departure time
to be 90 minutes past the arrival time Extra Credit:
Modify the TableNumbers property to not list any tables currently in use during during that time slot (a worthy challenge!)
Page 57
45 Minutes
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Web Development using C#
End of Session 1
Last Update: 1/12 Page 58