Before discussing the backend administrator system, there is
a little episode needed to be pointed out—the
placeholder page Admin_Admin.aspx.
About the placeholder page - Admin_Admin.aspx
When the user succeeds in logging into the system, he or she
will be navigated to page Admin_Admin.aspx. As you will later discover in the
source code, page Admin_Admin.aspx plays the role of a placeholder for us to
more easily add the ASP.NET 2.0 SiteMapPath control related navigator technique.
Figure 2 shows the running time interface when the administrator first logs in.
Figure 2 - The running time snapshot when the administrator
first logs in

As you see, the placeholder page does nothing but serve as a
simple placeholder in order to gain a coherent user experience with the ASP.NET
2.0 navigator support.
Now, let us first examine the blog category management block.
Blog Category Management - Admin_Type.aspx
The blog category management interface is the simplest yet most
typical one in the system, which embodies the typical ASP.NET 2.0 server
controls programming in combination with the ASP.NET AJAX server control
UpdatePanel. First take a look at the beginning running time snapshot for the
blog category management, as is shown in Figure 3.
Figure 3 - The running time snapshot for the blog
category management

As you have guessed, besides the left panel component that
derives from the master page and the navigating bar at the upper right, there
are four functionalities provided in this page: browse the blog category in
page navigating mode, edit the category, delete it, and add new one by clicking
button "Add new category."
It us worth noting that the first three functionalities have
been well supported by the ASP.NET 2.0 GridView control, but for some unknown
reason it has not had the built-in support for adding new records.
Now let us first review the conventional support of the
GridView control for browsing, editing, and deleting, all of which are accomplished
through the simple ASP.NET 2.0 declarative programming, as is indicated in
Listing 1 (for integrity we list all the HTML mark elements code in this page).
Listing 1 - The typical declarative GridView
control programming plus ASP.NET AJAX server-side control UpdatePanel
<%@ Page Language="C#" MasterPageFile="~/Admin.master" AutoEventWireup="true"
CodeFile="Admin_Type.aspx.cs" Inherits="Admin_Type" Title="Untitled Page"%>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
<script runat="server">
void btnCancel_Click(object sender, EventArgs e)
{
GridView1.ShowFooter = false;
}
void btnAdd_Click(object sender, EventArgs e)
{
TextBox ArticleCategory =
GridView1.FooterRow.FindControl("ArticleCategoryTextBox") as TextBox;
SqlDataSource1.InsertParameters["ST_c_name"].DefaultValue =
ArticleCategory.Text;
SqlDataSource1.Insert();
}
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1"
Runat="Server">
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<table style="width: 75%;">
<tr>
<td colspan="3">
<asp:SiteMapPath ID="SiteMapPath1" runat="server">
</asp:SiteMapPath>
</td>
</tr>
<tr>
<td colspan="3">
<table width="98%" border="2" cellpadding="0" cellspacing="0"
class="table" bordercolor="#006600">
<tr>
<td >
<asp:Button ID="outAdd" runat="Server"
Text="Add new category"
onclick="outAdd_Click" />
<asp:GridView ID="GridView1" runat="server"
AllowPaging="True"
AutoGenerateColumns="False" DataKeyNames="ST_c_id"
DataSourceID="SqlDataSource1" Width="487px"
ShowFooter="False">
<Columns>
<asp:TemplateField HeaderText="ST_c_id"
InsertVisible="false"
Visible="false">
<EditItemTemplate>
<asp:Label ID="Label1" runat="server" \
Text='<%# Eval("ST_c_id")%>' />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Bind("ST_c_id") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Category" >
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"
Text='<%# Bind("ST_c_name") %>' />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server"
Text='<%# Bind("ST_c_name")%>' />
</ItemTemplate>
<FooterTemplate
Runat="server" />
<asp:Button ID="btnAdd" Runat="server"
Text="Add" OnClick="btnAdd_Click" />
<asp:Button ID="btnCancel" Runat="server"
Text="Cancel" OnClick="btnCancel_Click" />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Operation" >
<EditItemTemplate>
<asp:LinkButton ID="LinkButton1"
runat="server" CausesValidation="True"
CommandName="Update" Text="Update"
BackColor="White"></asp:LinkButton>
<asp:LinkButton ID="LinkButton2"
runat="server" CausesValidation="False"
CommandName="Cancel" Text="Cancel"
BackColor="White"></asp:LinkButton>
</EditItemTemplate>
<ControlStyle ForeColor="#C00000" />
<ItemTemplate>
<asp:ImageButton ID="LinkButton1"
runat="server"
CausesValidation="False" CommandName="Edit"
ImageUrl="~/images/edit.gif"
ToolTip="Edit the current category">
</asp:ImageButton>
<asp:ImageButton ID="LinkButton3"
runat="server" CausesValidation="False"
CommandName="Delete"
OnClientClick="return confirm('Are you sure to delete this category?');"
ImageUrl="~/images/delete.gif"
ToolTip="Delete the current category">
</asp:ImageButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
DeleteCommand="DELETE FROM [ST_class] WHERE [ST_c_id] = @ST_c_id"
InsertCommand="INSERT INTO [ST_class] ([ST_c_name]) VALUES (@ST_c_name)"
SelectCommand="SELECT * FROM [ST_class] "
UpdateCommand="UPDATE [ST_class] SET [ST_c_name] = @ST_c_name WHERE [ST_c_id] = @ST_c_id">
<DeleteParameters>
<asp:Parameter Name="ST_c_id" Type="Int32" />
</DeleteParameters>
<UpdateParameters>
<asp:Parameter Name="ST_c_name" Type="String" />
</UpdateParameters>
<InsertParameters>
<asp:Parameter Name="ST_c_id" Type="Int32" />
<asp:Parameter Name="ST_c_name" Type="String" />
</InsertParameters>
</asp:SqlDataSource>
</td>
</tr>
</table>
</td>
</tr>
</table>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
To gain the paging support we set the GridView1's AllowPaging
property to true. To make the GridView1 support the editing operation related "update"
and "cancel" functions we must specify the UpdateCommand as well as
the UpdateParameters related contents as shown above. The same logic applies to
deleting function.
Next, let us check out how the adding (inserting) function
is accomplished. Enhancing the GridView control with insert operation has several
solutions you can retrieve from the Internet. So in this case, I will only present
to you one of these.
As you may have guessed, the tip lies in the Footer part of
the GridView control. To begin, we set the ShowFooter property to false. Next,
when the user wants to insert (or add) a new record he or she can click the button
"Add new category," which will trigger the handler outAdd_Click in
file Admin_Type.aspx.cs.
Listing 2
protected void outAdd_Click(object sender, EventArgs e)
{
GridView1.ShowFooter = true;
}
Then the footer part of GridView1 is displayed.
Figure 4 - Extend the GridView control to support inserting operation

When you enter a non-empty string and click "Add,"
the insert will succeed; or else, you can click "Cancel" to cancel
the current operation (hide the footer of the GridView control).
Herein you have to code the two buttons related click event
handlers in the inline mode.
Listing 3 - The inline mode click event handlers
<script runat="server">
void btnCancel_Click(object sender, EventArgs e)
{
GridView1.ShowFooter = false;
}
void btnAdd_Click(object sender, EventArgs e)
{
TextBox ArticleCategory =
GridView1.FooterRow.FindControl("ArticleCategoryTextBox") as TextBox;
if (ArticleCategory.Text.Trim() != "")
{
SqlDataSource1.InsertParameters["ST_c_name"].DefaultValue =
ArticleCategory.Text;
SqlDataSource1.Insert();
}
}
</script>
Otherwise, you will see a build error throw out
Figure 5 - In the ASP.NET content page mode too
deep level of programming requires the inline mode, otherwise you will get the related
build error

Last but not the least, the three modified operations are
done in the AJAX mode—all of the related
areas are enclosed using an UpdatePanel control.
In the above case, we have only introduced one of the cases of
the usage of the UpdatePanel control in terms of the master page. In fact, not
all ASP.NET 2.0 controls are compatible with the UpdatePanel control. That ASP.NET
2.0 controls are compatible with the UpdatePanel control implies that ASP.NET
2.0 controls can be put inside the UpdatePanel control. That some ASP.NET 2.0
controls are incompatible with the UpdatePanel control implies that some ASP.NET
2.0 controls cannot be put inside the UpdatePanel control. However, the ASP.NET
2.0 controls that are incompatible with the UpdatePanel control can still be put
on an ASP.NET AJAX page while the rest must be placed outside control UpdatePanel.
To sum up, the following ASP.NET 2.0 controls cannot be used
inside control UpdatePanel.
·
TreeView and Menu
·
WebParts
·
FileUpload (it cannot be used when sending out files in the
asynchronous way)
·
GridView and DetailsView controls with the
EnableSortingAndPagingCallbacks properties setting True. Note that, by default,
the EnableSortingAndPagingCallbacks properties of the both are set to false.
·
Substitution
·
Login, PasswordRecovery, ChangePassword, CreateUserWizard
controls that have not been changed into editable temples
·
Validators, including BaseCompareValidator, BaseValidator, CompareValidator,
CustomValidator, RangeValidator, RegularExpressionValidator,
RequiredFieldValidator, and ValidationSummary controls
All in all, there are many, many things about the
UpdatePanel control which can not be deeply researched in this article.
OK, let us next continue to see how the concrete blog
articles are managed.
Blog Article Management - Admin_Article.aspx
Look at the design-time layout of the web form Admin_Article.aspx,
as illustrated in Figure 6.
Figure 6 - The design-time snapshot of page Admin_Article.aspx

Page Admin_Article.aspx is also an ASP.NET AJAX typed
content page. The middle part of the page is an UpdatePanel-enclosed GridView
to show general blog info while the right is an UpdatePanel-enclosed DetailsView
to display the related detailed blog info when one of the blogs at the middle
part is clicked. Note the blog article deletion operation is directly done
inside the GridView control, while the editing and appending operations are
finished through the right part DetailsView. Moreover, if some error occurs
during the course of the above operations, the Label ErrorMessageLabel is used
to show the associated info, while when the editing is successfully done the
related updating time will also be shown at the lower right part of control DetailsView.
To make all of these a partial updating operation, we have also put them inside
the UpdatePanel control.
As of other AJAX related topics, there are also three points
deserved to be noticed. First, because the control DetailsView is surrounded alone
by an UpdatePanel UpdatePanel2, when the updating operation takes effect in it,
to achieve the result of synchronously update the data inside the GridView at
the middle part, we set the DetailsView as the PostBackTrigger trigger of
UpdatePanel UpdatePanel2, while GridView1 is set as the AsyncPostBackTrigger trigger.
At this rate, when you click "Select" link inside the GridView, the
contents in the right-side DetailsView control will be updated asynchronously,
while when you edit and update the data in the DetailsView control, the data inside
the middle GridView will be updated in the traditional post back way. Listing 4
below shows the related code.
Listing 4 - The PostBackTrigger and AsyncPostBackTrigger
triggers of control UpdatePanel2
<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
CellPadding="4" DataKeyNames="ST_n_id" DataSourceID="SqlDataSource3"
Font-Size="Smaller" Height="50px"
Width="472px" ForeColor="#333333" GridLines="None"
OnDataBound="DetailsView1_DataBound"
OnItemInserted="DetailsView1_ItemInserted"
OnItemUpdated="DetailsView1_ItemUpdated">
…… (omitted)
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="DetailsView1" />
<asp:AsyncPostBackTrigger ControlID="GridView1"
EventName="SelectedIndexChanged" />
<asp:AsyncPostBackTrigger ControlID="GridView1" EventName="RowDeleted" />
<asp:AsyncPostBackTrigger ControlID="GridView1" EventName="Sorted" />
<asp:AsyncPostBackTrigger ControlID="GridView1"
EventName="PageIndexChanged" />
</Triggers>
</asp:UpdatePanel>
Second, to gain the better user experience when users edit
the blog authoring related date time, we introduced the AJAX Control toolkit extender
CalendarExtender.
Listing 5 - The AJAX Control toolkit extender
CalendarExtender related code
<asp:TemplateField HeaderText="Date" SortExpression="ST_n_date">
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%# Bind("ST_n_date") %>' />
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="TextBox3" runat="server" Text='<%# Bind("ST_n_date") %>' />
<asp:Image runat="Server" ID="Image1"
ImageUrl="~/Images/Calendar_icon.gif"
ToolTip="Click the icon to show the calendar." />
<ajaxToolkit:CalendarExtender ID="CalendarExtender1" runat="server"
TargetControlID="TextBox3"
Format="MM/dd/yyyy"
FirstDayOfWeek="Monday"
PopupButtonID="Image1">
</ajaxToolkit:CalendarExtender>
</EditItemTemplate>
<InsertItemTemplate>
<asp:TextBox ID="TextBox3" runat="server" Text='<%# Bind("ST_n_date") %>' />
<asp:Image runat="Server" ID="Image2"
ImageUrl="~/Images/Calendar_icon.gif"
ToolTip="Click the icon to show the calendar." />
<ajaxToolkit:CalendarExtender ID="CalendarExtender2" runat="server"
TargetControlID="TextBox3"
Format="MM/dd/yyyy"
FirstDayOfWeek="Monday"
PopupButtonID="Image2">
</ajaxToolkit:CalendarExtender>
</InsertItemTemplate>
</asp:TemplateField>
If the blogger clicks the "Edit" link at the lower
right part, the control changes into editing mode. In the editing mode (or in
the insert mode), when the user clicks the calendar-shaped icon, a pop up
calendar is there for him or her to click the date time. When the click action
is over, newly-selected data is shown at the nearby textbox; all the update process
is clearly in the asynchronous means. Figure 7 shows one of the related
running-time snapshots when editing the date time of one blog.
Figure 7 - Use the AJAX Control toolkit extender
CalendarExtender to enhance the user experience when editing the date time

Third, as is shown in Figure 7, there is a happy face. This
just relates to our topic here. As emphasized above and still to gain a friendlier
user experience, we use the AJAX Control toolkit extender ToggleButtonExtender
to embroider the ASP.NET CheckBox control. In this case, a happy face (Smile.gif)
corresponds to property CheckedImageUrl of control ToggleButtonExtender, while a
sad face (Sad.gif) to property UncheckedImageUrl of it. Listing 6 shows the
related code.
Listing 6 - The AJAX Control toolkit extender
CalendarExtender related code
<asp:TemplateField HeaderText="Recommendable:" SortExpression="ST_n_iscmd">
<EditItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server"
Checked='<%# Bind("ST_n_iscmd") %>' />
<ajaxToolkit:ToggleButtonExtender ID="ToggleButtonExtender1"
runat="server" TargetControlID="CheckBox1"
CheckedImageAlternateText="Recommend"
CheckedImageUrl="Images/Smile.gif" ImageHeight="48"
ImageWidth="48" UncheckedImageAlternateText="No Recommending"
UncheckedImageUrl="Images/Sad.gif">
</ajaxToolkit:ToggleButtonExtender>
</EditItemTemplate>
<InsertItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server"
Checked='<%# Bind("ST_n_iscmd") %>' />
<ajaxToolkit:ToggleButtonExtender ID="ToggleButtonExtender2"
runat="server" TargetControlID="CheckBox1"
CheckedImageAlternateText="Recommend"
CheckedImageUrl="Images/Smile.gif"
ImageHeight="48" ImageWidth="48"
UncheckedImageAlternateText="No Recommending"
UncheckedImageUrl="Images/Sad.gif">
</ajaxToolkit:ToggleButtonExtender>
</InsertItemTemplate>
<HeaderStyle HorizontalAlign="Right" />
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" Checked='<%# Bind("ST_n_iscmd") %>'
Enabled="false" />
<ajaxToolkit:ToggleButtonExtender ID="ToggleButtonExtender3"
runat="server"
TargetControlID="CheckBox1"
CheckedImageAlternateText="Recommend"
CheckedImageUrl="Images/Smile.gif"
ImageHeight="48" ImageWidth="48"
UncheckedImageAlternateText="No Recommending"
UncheckedImageUrl="Images/Sad.gif">
</ajaxToolkit:ToggleButtonExtender>
</ItemTemplate>
</asp:TemplateField>
In this case, field ST_n_iscmd in table ST_news is a Boolean
type. When the value is set to true, it means the blogger recommends it to the
surfers; or else, non-recommendable. In traditional ASP.NET mode, we usually
use the checkbox control for the users to make the selection, while herein we
use a pair of images with contrary expressions to gain the AJAX styled user
experience.
Let us now shift our attention to the blog comments related programming.
Blog Comments Management - Admin_Comments.aspx
As is indicated from the menu on the left in the master page,
when you click hyperlink "Comments Management" you will be navigated
to page Admin_Comments.aspx. The page bears the responsibility of managing the
various comments made by valid blog readers. Herein, we have simplified the
design - merely performing the functionality of deleting selected comments. As
the many of the other parts in this system, this page is also an Ajax based content page with an ASP.NET GridView control to display the rough comment info
as well as accomplish the deleting operation. Figure 8 gives the design-time
snapshot to manage blog related comments.
Figure 8

Compared with the above pages, this one is pretty simple. However,
there are still three points worth noticing.
First, as is well known, the ASP.NET GridView control itself
does not support deleting more than one row of data records. However, in
practical scenarios this is often required so users can delete the entire
selected records one time to gain a better user experience. In this case, to
delete comments, the user can first check/uncheck the check boxes at the "Select"
column, and then click the button "Delete selected rows" to easily
remove all the selected records from the backend database. To make clearer the
how-tos, Listing 7 shows the related click event handler with detailed comments.
Listing 7
protected void DeleteSelectedRows_Click(object sender, EventArgs e)
{
//Iterate through all the GridView Rows
foreach (GridViewRow row in GridView1.Rows)
{
//Get the first column from the row where the HtmlInputCheckBox is located
TableCell cell = row.Cells[0];
//Get the HtmlInputChecklBox control from the cells control collection
HtmlInputCheckBox checkBox = cell.Controls[1] as HtmlInputCheckBox;
//If the checkbox exists and are checked, execute the
//Delete command where the
//value form the HtmlInputCheckBox?Value property is set
//as the value of the delete command parameter.
if (checkBox != null && checkBox.Checked)
{
SqlDataSource1.DeleteParameters["ST_r_id"].DefaultValue =
checkBox.Value;
SqlDataSource1.Delete();
}
}
lbInfo.Text = "The deletion has succeeded!";
}
The second point worth noticing is that to gain better and
safer user effects, when the user clicks "Delete selected rows" we
first display to him or her a friendly prompt dialog to confirm the current
deleting operation, as is done through the AJAX control toolkit extender ConfirmButtonExtender.
Listing 8 shows the related HTML code.
Listing 8 - Using the AJAX control toolkit extender
ConfirmButtonExtender to achieve the safer operation
<asp:Button ID="btnDel" runat="server" Text="Delete selected rows"
OnClick="DeleteSelectedRows_Click"/>
<asp:Label ID="lbInfo" runat="server" ForeColor="Red"></asp:Label>
<ajaxToolkit:ConfirmButtonExtender ID="cbe" runat="server"
TargetControlID="btnDel"
ConfirmText="Are you sure to delete all your selections?">
</ajaxToolkit:ConfirmButtonExtender>
Since the extender ConfirmButtonExtender is very easy to follow,
we won’t chatter much about it.
The third and the last point is, of course, the UpdatePanel
control that surrounds the one and only GridView control. As you may have
guessed, when the user confirms the current deleting operation, all the comment
data within the GridView control will be partially updated.
That is all for page Admin_Comments.aspx. The next page that
comes up is Admin_link.aspx.
The Link Management - Admin_link.aspx
The web form Admin_link.aspx takes charge of managing all
the blog host interested hyperlinks that will be shown at the left side of the
home page. Figure 9 gives the related design-time snapshot.
Figure 9 - The design-time snapshot of page Admin_link.aspx

From Figure 9, you can see that the layout and design of
this page is very much like those of page Admin_Comments.aspx in addition to
two aspects. One dissimilar point is the appearance of an "Add" and
the other is two AJAX control toolkit extender TextBoxWatermarkExtenders (which
are introduced to embroider the two nearby text boxes) are utilized. As of the
latter we select to omit it since the TextBoxWatermarkExtender extender has
been put in use and explained in the first installment of this series.
Now let us say a few words about the "Add" button.
In fact, this is also a simple and typical operation concerning the GridView
control.
To make things clearer, we still give the related code.
Listing 9 - The key HTML code of page Admin_link.aspx
<script runat="server">
void btnAdd_Click(object sender, EventArgs e) {
SqlDataSource1.InsertParameters["ST_l_name"].DefaultValue =
txtLinkName.Text;
SqlDataSource1.InsertParameters["ST_l_url"].DefaultValue =
txtLinkURL.Text;
SqlDataSource1.Insert();
}
</script>
…… (Omitted)
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
AutoGenerateColumns="False" DataKeyNames="ST_l_id"
DataSourceID="SqlDataSource1">
<Columns>
<asp:TemplateField HeaderText="Select">
<ItemTemplate>
<input id="LinkID" type="checkbox" runat="server"
value='<%# Eval("ST_l_id") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ST_l_id" HeaderText="Link ID"
InsertVisible="False"
ReadOnly="True" SortExpression="ST_l_id" />
<asp:BoundField DataField="ST_l_name" HeaderText="Link Name"
SortExpression="ST_l_name" />
<asp:BoundField DataField="ST_l_url" HeaderText="URL"
SortExpression="ST_l_url" />
</Columns>
</asp:GridView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnDel" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="btnAdd" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="SELECT [ST_l_id], [ST_l_name], [ST_l_url] FROM [ST_link]"
DeleteCommand="DELETE [ST_link] WHERE [ST_l_id] = @ST_l_id"
InsertCommand=
"INSERT INTO [ST_link] ([ST_l_name],[ST_l_url]) VALUES (@ST_l_name,@ST_l_url)">
<DeleteParameters>
<asp:Parameter Type= "Int32" Name="ST_l_id"></asp:Parameter>
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="ST_l_id" Type="Int32" />
<asp:Parameter Name="ST_l_name" Type="String" />
<asp:Parameter Name="ST_l_url" Type="String" />
</InsertParameters>
</asp:SqlDataSource>
…………… (Omitted)
<asp:Button ID="btnDel" runat="server" Text="Delete selected rows"
OnClick="DeleteSelectedRows_Click"/>
<asp:Label ID="lbInfo" runat="server" ForeColor="Red"></asp:Label>
<cc1:ConfirmButtonExtender ID="cbe" runat="server" TargetControlID="btnDel"
ConfirmText="Are you sure to delete all your selections?">
</cc1:ConfirmButtonExtender>
…………… (Omitted)
<asp:Label ID="Label1" runat="server" Text="Website Name:" />
<asp:TextBox ID="txtLinkName" runat="server" />
<br />
<asp:Label ID="Label2" runat="server" Text="Website URL:" />
<asp:TextBox ID="txtLinkURL" runat="server"></asp:TextBox>
<br />
<asp:Button ID="btnAdd" runat="server" Text="Add" OnClick="btnAdd_Click"/>
Note that all the deleting related operations are pretty
similar to those of the previous page. When "Add" is clicked, its
related click handler btnAdd_Click will be invoked. After populating all the
property InsertParameters related values method, Insert of SqlDataSource1 is
called. Then the adding operation is finished. As is clearly shown above, the "Add"
button is set as the trigger AsyncPostBackTrigger of the UpdatePanel control,
which, of course, will result in an AJAX styled updating with the GridView control
(enclosed by the UpdatePanel control).
Next, let us look into the final blog host (in this case
also the administrator) related management task—manipulating
the messages that are left by surfers, which is achieved through page Admin_Message.aspx.
Message Management - Admin_Message.aspx
Take a look at the design-time snapshot of page Admin_Message.aspx.
Figure 10

Well, since this page is nearly a copy of page Admin_Comments.aspx
we do not have to waste words on it. You can refer to the previously narrated
page Admin_Comments.aspx to follow up with it.
For now, we have finished up all the backend administrator (also
in this case the blog host) related tasks.