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

Pro Server Controls and AJAX Components phần 7 pot

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

CHAPTER 9 ■ ASP.NET AJAX CONTROLS AND EXTENDERS
437
// Control properties
get_highlightCssClass : function()
{
return this._highlightCssClass;
},
set_highlightCssClass : function(value)
{
if (this._highlightCssClass !== value)
{
this._highlightCssClass = value;
this.raisePropertyChanged('highlightCssClass');
}
},
get_nohighlightCssClass : function()
{
return this._nohighlightCssClass;
},
set_nohighlightCssClass : function(value)
{
if (this._nohighlightCssClass !== value)
{
this._nohighlightCssClass = value;
this.raisePropertyChanged('nohighlightCssClass');
}
}
}
// Optional descriptor for JSON serialization.
ControlsBook2Lib.Ch09.HighlightedHyperlink.descriptor =
{


properties: [ {name: 'highlightCssClass', type: String},
{name: 'nohighlightCssClass', type: String} ]
}
// Register the class as a type that inherits from Sys.UI.Control.
ControlsBook2Lib.Ch09.HighlightedHyperlink.registerClass('ControlsBook2Lib.Ch09.
HighlightedHyperlink', Sys.UI.Control);
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
Notice that the HighlightedHyperlink client-side component doesn’t need to know the
CSS class names in advance. The client-side component also contains an optional descriptor
for JSON serialization support. Figure 9-1 shows HighlightedHyperLink ASP.NET AJAX-enabled
server control in action in the HighlightedHyperLink web form.
Cameron_865-2C09.fm Page 437 Monday, February 18, 2008 4:15 PM
Simpo PDF Merge and Split Unregistered Version -
438
CHAPTER 9
■ ASP.NET AJAX CONTROLS AND EXTENDERS
Figure 9-1. The rendered HighlightedHyperLink web form in Firefox
The source code for the HighlightedHyperLink web form and code-behind file is shown in
Listings 9-13 and 9-14.
Listing 9-13. The HighlightedHyperLink Web Form .aspx Page File
<%@ Page Language="C#"
MasterPageFile="~/MasterPage/ControlsBook2MasterPage.Master"
AutoEventWireup="true" CodeBehind="HighlightedHyperlink.aspx.cs"
Inherits="ControlsBook2Web.Ch09.HighlightedHyperlink"
Title="HighlightedHyperLink Demo" %>
<%@ Register TagPrefix="apress" Namespace="ControlsBook2Lib.Ch09"
Assembly="ControlsBook2Lib" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadSection" runat="server">
<style type="text/css">
.Highlight

{
color: navy;
font-weight: bolder;
}
.NoHighlight
{
color: Green;
font-weight: lighter;
}
</style>
</asp:Content>
Cameron_865-2C09.fm Page 438 Monday, February 18, 2008 4:15 PM
Simpo PDF Merge and Split Unregistered Version -
CHAPTER 9 ■ ASP.NET AJAX CONTROLS AND EXTENDERS
439
<asp:Content ID="Content2" ContentPlaceHolderID="ChapterNumAndTitle" runat="server">
<asp:Label ID="ChapterNumberLabel" runat="server
Width="14px">9</asp:Label>&nbsp;&nbsp;<asp:Label
ID="ChapterTitleLabel" runat="server" Width="360px">
ASP.NET AJAX Controls and Extenders</asp:Label>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="PrimaryContent" runat="server">
<br />
<apress:HighlightedHyperLink ID="HighlightedHyperLink1"
HighlightCssClass="Highlight"
NoHighlightCssClass="NoHighlight" runat="server"
NavigateUrl="">Microsoft
</apress:HighlightedHyperLink><br />
<apress:HighlightedHyperLink ID="HighlightedHyperLink2"
HighlightCssClass="Highlight"

NoHighlightCssClass="NoHighlight" runat="server"
NavigateUrl="">Apress
</apress:HighlightedHyperLink><br />
<apress:HighlightedHyperLink ID="HighlightedHyperLink3"
HighlightCssClass="Highlight"
NoHighlightCssClass="NoHighlight" runat="server"
NavigateUrl="">
ASP.NET AJAX</apress:HighlightedHyperLink><br />
<apress:HighlightedHyperLink ID="HighlightedHyperLink4"
HighlightCssClass="Highlight"
NoHighlightCssClass="NoHighlight" runat="server"
NavigateUrl="">
MSDN Online</apress:HighlightedHyperLink><br />
<br />
</asp:Content>
Listing 9-14. The HighlightedHyperLink Web Form Code-Behind Class File
using System;
namespace ControlsBook2Web.Ch09
{
public partial class HighlightedHyperlink : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
This concludes our discussion of the HighlightedHyperLink ASP.NET AJAX server control.
Cameron_865-2C09.fm Page 439 Monday, February 18, 2008 4:15 PM
Simpo PDF Merge and Split Unregistered Version -
440

CHAPTER 9
■ ASP.NET AJAX CONTROLS AND EXTENDERS
Summary
In this chapter, we provided an overview of ASP.NET AJAX, both the server-side and client-side
functionality. ASP.NET AJAX includes a powerful client-side script library that provides cross-
browser compatibility, as well as a powerful client-side programming model that mimics
object-oriented behavior in JavaScript.
We covered the server-side programming model that requires implementation of the
GetScriptDescriptors and GetScriptReferences methods. We also explained how the server-
side configuration is passed to the client-side component utilizing the ScriptBehaviorDescriptor
class. Finally, we demonstrated how to implement both an ASP.NET AJAX server control by
implementing IScriptControl, as well as how to implement an extender control by inheriting
from the ExtenderControl base class.
For additional examples of ASP.NET AJAX server controls and extenders, we recommend
downloading and reviewing the ASP.NET AJAX Control Toolkit available at />ajax/ajaxcontroltoolkit/samples/.
Cameron_865-2C09.fm Page 440 Monday, February 18, 2008 4:15 PM
Simpo PDF Merge and Split Unregistered Version -
441
■ ■ ■
CHAPTER 10
Other Server Controls
Up to this chapter, we have focused on providing the necessary background to create powerful
ASP.NET server controls that support custom styling, templating, data binding, client-side
script, and ASP.NET AJAX. These development techniques and features can be put to work in
many different ways. In this part of the book, we begin to move on to advanced topics such web
part development and design-time support.
In this chapter, we begin our advanced topic journey by covering web part development
and adaptive control programming. We will start off with a discussion on building web parts
for both ASP.NET and Microsoft Office SharePoint Server 2007. Next, we will focus on adaptive
control development, including the mobile controls for devices. In the next section, we begin

our journey with web parts.
■Note For information on building custom validator controls, the MSDN documentation contains a nice set of
cross-browser validator control samples that also comply with the WWW Consortium DOM Level 1 specification; the
samples are located here: />Web-Part-Based Web Site Development
This chapter won’t attempt to provide a complete overview of the web part infrastructure and
development model available in ASP.NET, because the documentation does a very good job of
explaining what functionality is available. What I will do is provide a discussion on various web
part topics encountered while building out the example web parts in this chapter to help you
understand the moving parts available when building web parts. If you find that you need
more background information on a particular area, here is the top-level link to the ASP.NET
web parts documentation at MSDN Online:
/>From the preceding link, you can navigate to these sections for more detail on a partic-
ular topic:
• ASP.NET Web Parts Overview
• Web Parts Control Set Overview
Cameron_865-2C10.fm Page 441 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
442
CHAPTER 10
■ OTHER SERVER CONTROLS
• Web Parts Page Display Modes
• Web Parts Personalization
• Web Parts Connections Overview
For an idea of what’s possible, look no further than Microsoft Office SharePoint Server
(MOSS) 2007, which is built on top of ASP.NET and the web part infrastructure. A public-facing
Internet site built on top of MOSS with custom web parts is . Here is a link
to the first of a three-part series on how this site was built by Allin Consulting on MOSS and
ASP.NET web parts:
/>moss-has-got-game-glu-mobile-s-website-www-glu-com-how-we-did-it-part-1-of-3.aspx
With that background out of the way, we’ll dive into a discussion on web part development

in the next section.
Web Part Development
Web parts have existed in SharePoint for many years. Initially, the web part development
model was based on VBScript, which is not what most developers would call their favorite
development language or environment. In SharePoint Server 2003, Microsoft more closely
integrated SharePoint with ASP.NET, providing namespaces for supporting web part develop-
ment in .NET. With .NET Framework 2.0, the ASP.NET team integrated the web part infrastructure
and development model within ASP.NET itself. However, the two web part models remained
separate. Building web parts that targeted both ASP.NET 2.0 and SharePoint Server 2003 required
custom compilation, since different namespaces and base classes where required. In Microsoft
Office SharePoint Server (MOSS) 2007, SharePoint is completely integrated with and built on
ASP.NET 2.0. This means that you can build web parts for MOSS using the ASP.NET WebPart
base class.
■Note Microsoft recommends inheriting from the ASP.NET WebPart base class whether developing for
pure ASP.NET or SharePoint.
The next section provides a brief overview of the ASP.NET web part infrastructure to set
the state for building web parts that take advantage of this framework.
Web Part Infrastructure
One of the features of WebPart-based applications is personalization. WebParts can have attributes
configured with the PersonalizableAttribute so that a user can create a unique view on the
page. Personalization for an ASP.NET web site requires that the SQL personalization provider
is configured for the site.
Cameron_865-2C10.fm Page 442 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
CHAPTER 10 ■ OTHER SERVER CONTROLS
443
■Note Personalization requires that the <trust level="" /> element is configured for Medium in order
to access members in the SqlClient namespace.
The SqlPersonalizationProvider class is used to configure the personalization in SQL Server.
The ASP.NET SQL Server Registration Tool (Aspnet_regsql.exe) can be used to set up the

database location for web part personalization, among other databases such as the ASP.NET
membership database. The tool is located at \%windir%\Microsoft.NET\Framework\v2.0.50727,
or at the same location for a later version of the framework.
There is a section in the web.config file to declaratively configure web part personalization via
the WebPartsPersonalization class under <system.web> <WebParts> <personalization. . . > that
can be used to configure the web part environment. Refer to the MSDN documentation for
more information on the WebPartsPersonalization class.
Web parts are hosted within the rich web part infrastructure, so as you would expect, there
are additional customizations available for web part developers. Table 10-1 provides a list of
the most common overrides when creating a WebPart server control.
With that background out of the way, let’s move on to creating web parts in the next section.
Creating Web Parts
In this section, we create two server controls and demonstrate them in a basic ASPX page. Next,
we convert the server controls to web parts and then demonstrate them in a web part portal page.
Table 10-1. WebPart Common Overrides
WebPart Member Overview
"Allow" properties These are behavior-focused properties that control developers
may want to manage for the logic of their custom WebPart control.
Examples are AllowClose, AllowConnect, and AllowEdit.
CreateChildControls It is quite common to build web parts based on composite server
controls to encapsulate chunks of functionality as a WebPart control.
CreateEditorParts Web parts can have custom editor web parts based on EditorPart
to enable users to edit custom web part properties. Override
CreateEditorParts to incorporate the custom EditorPart control.
PersonalizableAttribute This attribute is applied to properties of the custom web part that
the user may want to save unique settings to.
Rendering methods As with custom server controls, sometimes you may need to
override Render or RenderContents to completely change the
outputted HTML or to simply customize it by also calling the
base method.

Verbs Add custom WebPartVerb objects to the Verbs collection to allow
custom menu actions to appear along with the standard verbs
such as close or minimize.
Cameron_865-2C10.fm Page 443 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
444
CHAPTER 10
■ OTHER SERVER CONTROLS
This may seem like the long road to building web parts, but we believe it is more realistic.
In many situations, developers will create server controls and statically code the page layout
and what server controls appear on a page as part of an application. Initially, there are perhaps
just a couple of server controls, but after a couple of cycles where users ask for additional func-
tionality or views on data, developers may find themselves with a library of server controls with
different users requesting multiple combinations of server controls, resulting in multiple, hand-
coded, statically linked and created web forms. At this point, the developer may ask, “Why not
create a web part portal page where users can pick which controls display on the page, how the
controls are laid out, and which controls are linked?”
Regarding what type of scenario may fit this model, a reporting web portal or business
intelligence application comes to mind, so our focus for this demonstration is providing a
reporting page focused on the famous Northwind database with NorthWind customers as the
theme for the site.
In the next section, we build the server controls web form with two server controls reporting
NorthWind customer data.
The Server Controls
As mentioned in the previous section, we start out by creating server control versions of the
web parts and then show how to turn them into web parts in the next section. The two server
controls retrieve data from the NorthWind database. The first server control displays a list of
customers and allows editing of existing customers but not insertion or deletion. The second
server control takes a customer ID and displays invoice highlights for the customer based on
the provided customer ID. Both server controls allow sorting and paging, as well as provide a

simple style to show row highlighting.
If you have read this book straight through, you can probably guess that each of the two
server controls detailed here is a composite control containing a GridView and a DataSource
control and inheriting from CompositeControl. All of those guesses would be correct. Listing
10-1 contains the CustomerList custom server control.
Listing 10-1. The CustomerList Server Control
using System;
using System.Drawing;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace ControlsBook2Lib.Ch10
{
[ToolboxData("<{0}:CustomerList runat=server></{0}:CustomerList>")]
public class CustomerList : CompositeControl
{
private const string strSelectCmd = @"Select * from [Customers]";
private const string strUpdateCmd = @"UPDATE [Customers] SET " +
@"[CompanyName] = @CompanyName, [ContactName] = @ContactName, " +
@"[Phone] = @Phone WHERE [CustomerID] = @CustomerID";
Cameron_865-2C10.fm Page 444 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
CHAPTER 10 ■ OTHER SERVER CONTROLS
445
public CustomerList()
{
}
public String CustomerID
{
get
{

object customerID = ViewState["CustomerID"];
if (customerID == null)
return String.Empty;
else
return (String)customerID;
}
set
{
ViewState["CustomerID"] = value;
}
}
// Allow page developers to set the connection string.
public String ConnectionString
{
get
{
object connectionString = ViewState["ConnectionString"];
if (connectionString == null)
return String.Empty;
else
return (String)connectionString;
}
set
{
ViewState["ConnectionString"] = value;
}
}
public Boolean AllowCustomerEditing
{
get

{
object allowEditing = ViewState["AllowCustomerEditing"];
if (allowEditing == null)
return false;
else
return (Boolean)allowEditing;
}
Cameron_865-2C10.fm Page 445 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
446
CHAPTER 10
■ OTHER SERVER CONTROLS
set
{
ViewState["AllowCustomerEditing"] = value;
}
}
protected override void CreateChildControls()
{
Controls.Clear();
SqlDataSource ds = new SqlDataSource(this.ConnectionString, strSelectCmd);
ds.ID = "dsCustomers";
ds.DataSourceMode = SqlDataSourceMode.DataSet;
ds.UpdateCommandType = SqlDataSourceCommandType.Text;
ds.UpdateCommand = strUpdateCmd;
ParameterCollection updateParams = new ParameterCollection();
updateParams.Add(_createParameter("CustomerID", TypeCode.String));
updateParams.Add(_createParameter("CompanyName", TypeCode.String));
updateParams.Add(_createParameter("ContactName", TypeCode.String));
updateParams.Add(_createParameter("Phone", TypeCode.String));

Controls.Add(ds);
Label title = new Label();
title.Text = "Customer list";
Controls.Add(title);
LiteralControl br = new LiteralControl("<br/>");
Controls.Add(br);
GridView grid = new GridView();
grid.ID = "customerGrid";
grid.Font.Size = 8;
grid.AllowPaging = true;
grid.AllowSorting = true;
grid.AutoGenerateColumns = false;
String[] fields = { "CustomerID" };
grid.DataKeyNames = fields;
grid.DataSourceID = "dsCustomers";
CommandField controlButton = new CommandField();
//Only show Edit button if control configured to allow it
if (AllowCustomerEditing)
controlButton.ShowEditButton = true;
Cameron_865-2C10.fm Page 446 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
CHAPTER 10 ■ OTHER SERVER CONTROLS
447
controlButton.ShowSelectButton = true;
grid.Columns.Add(controlButton);
BoundField customerID = _createBoundField("CustomerID");
customerID.ReadOnly = true;
grid.Columns.Add(customerID);
grid.Columns.Add(_createBoundField("CompanyName"));
grid.Columns.Add(_createBoundField("ContactName"));

grid.Columns.Add(_createBoundField("Phone"));
grid.SelectedRowStyle.BackColor = Color.AntiqueWhite;
grid.SelectedIndexChanged += new EventHandler(SelectedIndexChanged);
grid.PageIndexChanged += new EventHandler(PageIndexChanged);
Controls.Add(grid);
Style.Add(HtmlTextWriterStyle.FontFamily, "arial");
BorderStyle = BorderStyle.Solid;
BorderColor = Color.LightBlue;
}
protected void SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow row = ((GridView)(sender)).SelectedRow;
CustomerID = row.Cells[1].Text;
}
protected void PageIndexChanged(object sender, EventArgs e)
{
((GridView)(sender)).SelectedIndex = -1;
}
private BoundField _createBoundField(String fieldName)
{
BoundField field = new BoundField();
switch (fieldName)
{
case "CompanyName": field.HeaderText = "Company Name";
break;
case "ContactName": field.HeaderText = "Contact Name";
break;
case "PhoneName": field.HeaderText = "Phone Name";
break;
case "CustomerID": field.HeaderText = "Customer ID";

break;
default: field.HeaderText = fieldName; break;
}
Cameron_865-2C10.fm Page 447 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
448
CHAPTER 10
■ OTHER SERVER CONTROLS
field.SortExpression = fieldName;
field.DataField = fieldName;
return field;
}
private Parameter _createParameter(String paramName, TypeCode dataTypeCode)
{
Parameter theParm = new Parameter(paramName, dataTypeCode);
return theParm;
}
}
}
The CustomerID property is used to store the selected row’s CustomerID value from the
customer list. The ConnectionString is a public property for the SqlDataSource control that is
part of the server control hierarchy to use to connect to the database. The CustomerList server
control allows editing of the customer list. The AllowCustomerEditing property is used to
control whether the editing is permitted for a particular instance of the control on a web form.
As with all composite server controls, CreateChildControls does all of the heavy lifting to
build out the server control hierarchy. The controls include a Label for the title, a LiteralControl to
contain a br tag, a SqlDataSource, and, of course, the GridView control.
The CreateChildControls override attaches two events to the GridView control, one
for the SelectedIndexChanged event and the other for the PageIndexChanged event. The
SelectedIndexChanged event sets the CustomerID property to the CustomerID value from the

GridView. The PageIndexChanged event resets the SelectedIndex to –1 so that a row is not selected
after the page is changed. The CustomerInvoices server control is similar to the CustomerList
server control, except that it is based on a database view instead of a table and so does not allow
editing. Listing 10-2 shows the source code for the CustomerInvoices server control.
Listing 10-2. The CustomerInvoices Server Control
using System;
using System.Drawing;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace ControlsBook2Lib.Ch10
{
[ToolboxData("<{0}:CustomerInvoices runat=server></{0}:CustomerInvoices>")]
public class CustomerInvoices : CompositeControl
{
private const string strSelectCmd = @"Select * from [Invoices] where "+
"CustomerID = '{0}'";
Cameron_865-2C10.fm Page 448 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
CHAPTER 10 ■ OTHER SERVER CONTROLS
449
public CustomerInvoices()
{
}
public String CustomerID
{
get
{
object customerID = ViewState["CustomerID"];
if (customerID == null)
return String.Empty;

else
return (String)customerID;
}
set
{
ViewState["CustomerID"] = value;
}
}
// Allow page developers to set the connection string.
public String ConnectionString
{
get
{
object connectionString = ViewState["ConnectionString"];
if (connectionString == null)
return String.Empty;
else
return (String)connectionString;
}
set
{
ViewState["ConnectionString"] = value;
}
}
protected override void CreateChildControls()
{
Controls.Clear();
SqlDataSource ds = new SqlDataSource(this.ConnectionString,
String.Format(strSelectCmd,CustomerID));
ds.ID = "dsCustomerInvoices";

ds.DataSourceMode = SqlDataSourceMode.DataSet;
Controls.Add(ds);
Cameron_865-2C10.fm Page 449 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
450
CHAPTER 10
■ OTHER SERVER CONTROLS
Label title = new Label();
title.Text = "Customer Invoices - "+ CustomerID;
Controls.Add(title);
LiteralControl br = new LiteralControl("<br/>");
Controls.Add(br);
GridView grid = new GridView();
grid.ID = "customerInvoicesGrid";
grid.Font.Size = 8;
grid.AllowPaging = true;
grid.PageSize = 5;
grid.AllowSorting = true;
grid.AutoGenerateColumns = false;
String[] fields = { "CustomerID" };
grid.DataKeyNames = fields;
grid.DataSourceID = "dsCustomerInvoices";
CommandField controlButton = new CommandField();
controlButton.ShowSelectButton = true;
grid.Columns.Add(controlButton);
grid.Columns.Add(_createBoundField("OrderID"));
grid.Columns.Add(_createBoundField("RequiredDate"));
grid.Columns.Add(_createBoundField("ShippedDate"));
grid.Columns.Add(_createBoundField("ProductName"));
grid.Columns.Add(_createBoundField("Quantity"));

grid.SelectedRowStyle.BackColor = Color.AntiqueWhite;
grid.SelectedIndexChanged += new EventHandler(SelectedIndexChanged);
grid.PageIndexChanged += new EventHandler(PageIndexChanged);
Controls.Add(grid);
Style.Add(HtmlTextWriterStyle.FontFamily, "arial");
BorderStyle = BorderStyle.Solid;
BorderColor = Color.LightBlue;
}
protected void SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow row = ((GridView)(sender)).SelectedRow;
}
Cameron_865-2C10.fm Page 450 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
CHAPTER 10 ■ OTHER SERVER CONTROLS
451
protected void PageIndexChanged(object sender, EventArgs e)
{
((GridView)(sender)).SelectedIndex = -1;
}
private BoundField _createBoundField(String fieldName)
{
BoundField field = new BoundField();
switch (fieldName)
{
case "Order ID": field.HeaderText = "Order ID";
break;
case "RequiredDate": field.HeaderText = "Required Date";
break;
case "ShippedDate": field.HeaderText = "Shipped Date";

break;
case "ProductName": field.HeaderText = "Product Name";
break;
case "Quanity": field.HeaderText = "Quantity Ordered";
break;
default: field.HeaderText = fieldName; break;
}
field.DataField = fieldName;
field.SortExpression = fieldName;
return field;
}
private Parameter _createParameter(String paramName, TypeCode dataTypeCode)
{
Parameter theParm = new Parameter(paramName, dataTypeCode);
return theParm;
}
}
}
Both controls have two helper methods for building out the control hierarchy; they are
named _createBoundField and _createParameter, and they help to create the bound fields and
parameters for the GridView control. The demonstration web form for the two server controls
is CustomerInfo.aspx. The source code is shown in Listings 10-3 and 10-4.
Cameron_865-2C10.fm Page 451 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
452
CHAPTER 10
■ OTHER SERVER CONTROLS
Listing 10-3. The Customer Information Web Form .aspx Page File
<%@ Page Language="C#"
MasterPageFile="~/MasterPage/ControlsBook2MasterPage.Master"

AutoEventWireup="true" CodeBehind="CustomerInfo.aspx.cs"
Inherits="ControlsBook2Web.Ch10.CustomerInfo"
Title="Customer Info Demo Web Form" %>
<%@ Register assembly="ControlsBook2Lib" namespace="ControlsBook2Lib.Ch10"
tagprefix="apress" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadSection" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ChapterNumAndTitle" runat="server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="PrimaryContent" runat="server">
<br />
<br />
<apress:CustomerList ID="CustomerList1" runat="server"
ConnectionString = "<%$ ConnectionStrings:NorthWindDB %>"
AllowCustomerEditing="True" />
<br /> <br />
<apress:CustomerInvoices ID="CustomerInvoices1" runat="server" CustomerID="VINET"
ConnectionString = "<%$ ConnectionStrings:NorthWindDB %>" />
<br /> <br />
</asp:Content>
Listing 10-4. The Customer Information Web Form Code-Behind Class File
using System;
namespace ControlsBook2Web.Ch10
{
public partial class CustomerInfo : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
}

}
Figure 10-1 shows how the customer information web form application appears in
the browser.
We could wire up these controls by bubbling up the SelectedIndexChanged event for the
GridView to the CustomerList parent control as shown in Chapter 5, so that we can get the
customer ID and then pass it to the CustomerInvoices control, but we want to link the controls
using the web part, which we cover in the next section when we convert the server controls into
web parts.
Cameron_865-2C10.fm Page 452 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
CHAPTER 10 ■ OTHER SERVER CONTROLS
453
Figure 10-1. The Customer Info web form in the browser
Converting to WebPart Controls
To start the conversion, we copied the CustomerList and CustomerInvoices server control to
new class files with the same names but with the term “WebPart” appended. To start, System.Web.
UI.WebControls.WebParts was added to the class files, and the base control changed from
CompositeControl to WebPart.
At this point, the project compiles. As a test, we begin by creating the test form to see if the
web parts will host in a WebPartZone control. We added a page, CustomerInfoWebPart.aspx, to
the web project. Next, we added WebPartZone and ZoneTemplate controls to contain the two web
parts. A required step is to add a WebPartManager control to the page to enable web part function-
ality. Figure 10-2 shows the results of this minimalist effort.
Cameron_865-2C10.fm Page 453 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
454
CHAPTER 10
■ OTHER SERVER CONTROLS
Figure 10-2. The Customer Info web part basic web form in the browser
The web form renders with the additional chrome of the web parts around the controls,

including the basic web part menu containing just the Minimize and Close commands, but this
version of the web page is not much different from the server control version. We next discuss
how to enable different web part modes, such as design.
Cameron_865-2C10.fm Page 454 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
CHAPTER 10 ■ OTHER SERVER CONTROLS
455
The WebPartPageController Server Control
Part of the allure of web forms with web parts is the ability to provide to end users design-time
functionality normally in the hands of developers. The WebPartPageController server control
provides a menu to do this by plugging into the web part page functionality. One example
behavior is the ability to move the location of web parts by entering design mode for the page.
Once finished designing the page, the end user can choose browse mode in the drop-down
menu. The WebPartPageController control also allows the user to choose whether to save
personalization data at the User or Shared scope. One consideration would be to apply role
checking on this setting if only certain users should be able to select the Shared scope. Figure 10-3
shows WebpartPageController in action.
Figure 10-3. WebpartPageController in the browser
Figure 10-4 shows the form in design mode with the mouse dragging
CustomerInvoicesWebPart to the top of the web part zone within the browser.
Cameron_865-2C10.fm Page 455 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
456
CHAPTER 10
■ OTHER SERVER CONTROLS
Figure 10-4. The Customer Info web part web form in design mode
What is handy about this server control is that just by dropping it on to the web-part-enabled
web form, you get immediate customization functionality. Listing 10-5 provides the source
code for the WebPartController server control.
Listing 10-5. The WebPartPageController Server Control

using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
Cameron_865-2C10.fm Page 456 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
CHAPTER 10 ■ OTHER SERVER CONTROLS
457
namespace ControlsBook2Lib.Ch10
{
[DefaultProperty("DisplayModeText")]
[ToolboxData("<{0}:WebPartPageController runat=server>
</{0}:WebPartPageController>")]
public class WebPartPageController : CompositeControl
{
WebPartManager _currentWebPartManager;
Label displayMode;
DropDownList displayModeDropDown;
RadioButton userRB;
RadioButton sharedRB;
Panel personalizationScopePanel;
#region Properties
[Bindable(true), Category("Appearance"), DefaultValue("Display Mode"),
Localizable(true), Description(
"Sets the text on the caption for the web part state dropdown.")]
public string DisplayModeText
{
get

{
object displayModeText = ViewState["DisplayModeText"];
if (displayModeText == null)
return string.Empty;
else
return (string)displayModeText;
}
set
{
ViewState["DisplayModeText"] = value;
}
}
[Bindable(true), Category("Appearance"), DefaultValue("Reset User State"),
Localizable(true), Description(
"Configures the text on the link button to reset state.")]
public string ResetStateText
{
get
{
object resetStateText = ViewState["ResetStateText"];
if (resetStateText == null)
return string.Empty;
Cameron_865-2C10.fm Page 457 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
458
CHAPTER 10
■ OTHER SERVER CONTROLS
else
return (string)resetStateText;
}

set
{
ViewState["ResetStateText"] = value;
}
}
[Bindable(true), Category("Appearance"), Localizable(true),
DefaultValue("Reset the current user's personalization data for the page."),
Description("Configures the tooltip for the link button to reset state.")]
public string ResetStateToolTip
{
get
{
object resetStateToolTip = ViewState["ResetStateToolTip"];
if (resetStateToolTip == null)
return string.Empty;
else
return (string)resetStateToolTip;
}
set
{
ViewState["ResetStateToolTip"] = value;
}
}
#endregion
#region Overrides
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
_currentWebPartManager =
WebPartManager.GetCurrentWebPartManager(Page);

}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
String browseModeName = WebPartManager.BrowseDisplayMode.Name;
Cameron_865-2C10.fm Page 458 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
CHAPTER 10 ■ OTHER SERVER CONTROLS
459
//Reset items collection on dropdown
displayModeDropDown.Items.Clear();
// Fill the DropDown with the names of supported display modes.
foreach (WebPartDisplayMode mode
in _currentWebPartManager.SupportedDisplayModes)
{
String modeName = mode.Name;
// Make sure a mode is enabled before adding it.
if (mode.IsEnabled(_currentWebPartManager))
{
ListItem item = new ListItem(modeName, modeName);
displayModeDropDown.Items.Add(item);
}
}
// If shared scope is allowed for this user, display the scope-switching
// UI and select the appropriate radio button for the current user scope.
if (_currentWebPartManager.Personalization.CanEnterSharedScope)
{
personalizationScopePanel.Visible = true;
if (_currentWebPartManager.Personalization.Scope
== PersonalizationScope.User)

userRB.Checked = true;
else
sharedRB.Checked = true;
}
ListItemCollection items = displayModeDropDown.Items;
int selectedIndex =
items.IndexOf(items.FindByText(_currentWebPartManager.DisplayMode.Name));
displayModeDropDown.SelectedIndex = selectedIndex;
}
public override ControlCollection Controls
{
get
{
EnsureChildControls();
return base.Controls;
}
}
public override Unit Height
{
Cameron_865-2C10.fm Page 459 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
460
CHAPTER 10
■ OTHER SERVER CONTROLS
get
{
return base.Height;
}
set
{

EnsureChildControls();
Unit min = new Unit(87);
if (value.Value > min.Value)
base.Height = value;
else
base.Height = min;
}
}
public override Unit Width
{
get
{
return base.Width;
}
set
{
EnsureChildControls();
Unit min = new Unit(167);
if (value.Value >= min.Value)
base.Width = value;
else
base.Width = min;
}
}
protected override void CreateChildControls()
{
Controls.Clear();
CreateChildControlHierarchy();
}
#endregion

private void CreateChildControlHierarchy()
{
Panel rootPanel = new Panel
{
ID = "rootPanel",
BorderWidth = 1,
BackColor = this.BackColor,
Cameron_865-2C10.fm Page 460 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -
CHAPTER 10 ■ OTHER SERVER CONTROLS
461
ForeColor = this.ForeColor
};
rootPanel.Font.Names = new string[] { "Verdana", "Arial", "Sans Serif" };
rootPanel.Width = this.Width;
rootPanel.Height = this.Height;
Controls.Add(rootPanel);
displayModeDropDown = new DropDownList
{
ID = "displayModeDropDown",
AutoPostBack = true,
Width = 120
};
displayModeDropDown.SelectedIndexChanged += new
EventHandler(displayModeDropDown_SelectedIndexChanged);
displayMode = new Label
{
ID = "displayMode",
Text = DisplayModeText,
AssociatedControlID = "DisplayModeDropDown"

};
displayMode.Font.Bold = true;
displayMode.Font.Size = 8;
//Add in order of desired rendering
rootPanel.Controls.Add(displayMode);
HtmlGenericControl div1 = new HtmlGenericControl("div");
div1.Controls.Add(displayModeDropDown);
rootPanel.Controls.Add(div1);
LinkButton resetUserState = new LinkButton
{
ID = "resetUserState",
Text = ResetStateText,
ToolTip = ResetStateToolTip
};
resetUserState.Font.Size = 8;
resetUserState.Click += new EventHandler(resetUserState_Click);
HtmlGenericControl div2 = new HtmlGenericControl("div");
div2.Controls.Add(resetUserState);
rootPanel.Controls.Add(div2);
personalizationScopePanel = new Panel
{
ID = "personalization Scope",
GroupingText = "Personalization Scope",
Cameron_865-2C10.fm Page 461 Thursday, February 21, 2008 1:01 PM
Simpo PDF Merge and Split Unregistered Version -

×