Pro ASP.NET 2.0 In CSharp 2005 (2005) [eng]
.pdf
1048 CHAPTER 31 ■ PORTALS WITH WEB PART PAGES
As you can see, the page now contains three zones: two zones for adding custom web parts to the page and one special zone. The special zone is a CatalogZone, which displays every web part that is available for the current page. It displays the list of available web parts and allows the user to select web parts from this list and add them to the page. In the designer, the code presented previously looks like Figure 31-3.
Figure 31-3. Web part pages in the Visual Studio designer
Adding Web Parts to the Page
Now you can start adding web parts to the web page. A web part is basically an ASP.NET control. You can use any type of control, including existing server controls, existing user controls, and custom server controls you have created on your own. You don’t even need to implement any special interfaces if you don’t need to interact with the web parts infrastructure or with other web parts on the page. Adding controls to a web part page is as simple as adding controls to a basic page. The only difference is that you add the controls to one of the previously added WebPartZones instead of to the page directly. For this purpose, WebPartZones use templates. The concept is the same as with grid controls, where you can specify a template that is created for every row in the grid. The template just defines the appearance of the web part. You can add existing server controls to a zone as follows:
<asp:WebPartZone runat="server" ID="HelpZone"> <ZoneTemplate>
<asp:Calendar runat="server" ID="MyCalendar" /> <asp:FileUpload ID="FileUpload1" runat="server" />
</ZoneTemplate>
</asp:WebPartZone>
CHAPTER 31 ■ PORTALS WITH WEB PART PAGES |
1049 |
The previous example shows the WebPartZone you added earlier in this chapter for the right section of your page. This zone now contains two controls: the standard Calendar control as well as a FileUpload control. Figure 31-4 shows the page in the Visual Studio designer after you have added this zone template.
Figure 31-4. A WebPartZone with controls added
Of course, you can create one or more user controls and add them to one of the web part zones. For example, create the database tables shown in Figure 31-5, and fill in some test records so that you can use them for extending the sample later.
Based on the Customer table, we will show you how to create your first web part now. Just add a new user control to your solution, open the database in the Server Explorer, and drag and drop the Customer table from the Server Explorer on your server control. The designer automatically creates the data source as well as a GridView that displays the data. (Don’t autoformat the GridView; this will happen automatically later, based on the WebPartZone controls.) Now you can add the newly created user control to your main web part zone by dragging it from the Solution Explorer onto the web part zone. Basically, the designer creates the necessary entries for registering the control in your page and then adds the control to the web part zone.
<asp:WebPartZone runat="server" ID="MainZone"> <ZoneTemplate>
<uc1:Customers ID="MyCustomers" runat="server" /> </ZoneTemplate>
</asp:WebPartZone>
1050 CHAPTER 31 ■ PORTALS WITH WEB PART PAGES
Figure 31-5. Database tables for the sample solution
Finally, you can add a special web part to the previously added CatalogZone control. Because this zone is used to display catalogs of web parts, you can add only special controls such as the PageCatalogPart to this zone. You add special controls in the same way that you add normal WebPartZone controls—through a ZoneTemplate.
<asp:CatalogZone runat="server" ID="SimpleCatalog"> <ZoneTemplate>
<asp:PageCatalogPart runat="server" ID="MyCatalog" /> </ZoneTemplate>
</asp:CatalogZone>
Before you start the web application, you can autoformat WebPartZone controls by opening the smart tag for the corresponding zone. You will see that formatting applies automatically to every control that is placed directly into a zone. Next, test the application by running your created web part page, and then you can debug the page. When you start the solution for debugging the page, you will see the screen in Figure 31-6 (depending on your autoformat selections).
You may notice that for every web part a title and a box for minimizing and restoring the web part is displayed with default captions. Later in the “Customizing the Page” section, you will learn how to customize these captions.
Because you have not configured any authentication method yet, by default the application uses Windows authentication. Therefore, you can customize the web part page in terms of minimizing single parts and closing single parts. Without any additional effort, the same is true when you authenticate your users through forms authentication (either with or without using the Membership API introduced in Chapter 21). So far, you cannot move web parts from one zone to another. To do this, you have to switch to a special page mode that you will learn about in the next section. When you close the browser and start another browser session, the page appears in the same layout as when you left it. That’s because the WebPartManager stores your changes in the personalization store.
CHAPTER 31 ■ PORTALS WITH WEB PART PAGES |
1051 |
Figure 31-6. The web part page displayed in the browser
Again, by default these settings are stored in the SQL Server 2005–based ASPNETDB.MDF database that is stored in the App_Data directory if you have not changed any configuration settings. You can change this default behavior by creating a database on the server of your choice using aspnet_regsql.exe. (This tool works with SQL Server only; for other databases, you have to create your own provider.) You can configure the provider with this database as follows:
<webParts>
<personalization defaultProvider="MyProvider"> <providers>
<add name="MyProvider" type="System.Web.UI.WebControls.WebParts.SqlPersonalizationProvider" connectionStringName="CustomSqlConnection" />
</providers>
</personalization>
</webParts>
You have to add the connection string (CustomSqlConnection in this example) to the <connectionStrings> section of the configuration file, and it should point to the database created with aspnet_regsql.exe.
Customizing the Page
At this point in the example, you can customize some parts of the web part page; you can minimize and restore web parts, and you can close web parts. But adding web parts previously closed to the web part page is not possible, as the CatalogZone with the PageCatalogPart does not display automatically. In addition, you are not able to change the position of web parts by simply dragging and dropping them from one zone to another.
The reason for this is that a web part page supports multiple display modes, and you have to be in the correct mode to do this. You can configure these display modes through the WebPartManager’s DisplayMode property. Table 31-1 lists the available display modes that are specified in the WebPartDisplayMode enumeration.
1052 CHAPTER 31 ■ PORTALS WITH WEB PART PAGES
Table 31-1. Web Part Page Display Modes
Mode |
Description |
Browse |
This is the default mode and is used for displaying contents of a web part page. |
Design |
When activating this mode, the user can change the position of web parts by |
|
dragging and dropping. |
Catalog |
If activated, the WebPartManager displays the catalog web part, which allows the |
|
user to add web parts to the web part page. |
Connect |
When activated, the user can configure connections between connectable web parts |
|
(more about this later in this section). |
Edit |
Allows the user to edit properties of web parts. This mode displays web parts of an |
|
editor. The EditorZone control is one of the prebuilt web part zones that allow you |
|
to display web part editor controls, which allow the user to modify settings for web |
|
parts. |
|
|
Now, add a Menu control to the first row of your layout table, as follows:
<table width="100%">
<tr valign="middle" bgcolor="#00ccff"> <td colspan="2" style="height: 104px">
<span style="font-size: 16pt; font-family: Verdana"> <strong>Welcome to web part pages!</strong>
</span>
</td>
<td style="height: 104px">
<asp:Menu ID="PartsMenu" runat="server" OnMenuItemClick="PartsMenu_MenuItemClick">
</asp:Menu>
</td>
</tr>
...
</table>
Next, you can create code in your page that populates the menu with all the available display modes for the WebPartManager. To do this, you just need to iterate through the DisplayModes property, which actually is a collection of WebPartDisplayMode items, and verify whether the mode is available. If it is available, just add it to the menu.
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
MenuItem Root = new MenuItem("Select Mode");
foreach (WebPartDisplayMode mode in MyPartManager.DisplayModes)
{
if (mode.IsEnabled(MyPartManager))
{
Root.ChildItems.Add(new MenuItem(mode.Name));
}
}
PartsMenu.Items.Add(Root);
}
}
1054 CHAPTER 31 ■ PORTALS WITH WEB PART PAGES
custom web part from scratch, you can define properties on the class that are stored in the personalization store. By doing this you can specify whether personalization happens on a per-user basis or is shared across authenticated users. You will learn how to do this in the next section.
Creating Web Parts
Now that you know the steps for creating web part pages with ASP.NET 2.0, it’s time to take a closer look at web part development. As you know, a web part can be any type of ASP.NET control, including user controls, built-in or custom server controls, and ASP.NET controls directly inherited from the WebPart base class of the new namespace System.Web.UI.WebControls.WebParts.
You have seen that every web part on your page automatically gets a default caption and default menus for minimizing and restoring the web part. Now it’s time to learn how you can customize this text and add menu entries (called verbs) to your custom web part. Any web part can provide custom public properties that the user can modify through an editor web part, which can be added to a web part called EditorZone. This EditorZone is displayed when the web part page is switched to the Edit mode, as introduced in Table 31-1. To do this, you have to create a separate editor part for your web part and somehow connect them. The next section shows how to do this.
Finally, web parts can communicate with other web parts through a well-defined mechanism. Therefore, these web parts exchange data and display information based on events that happen in other web parts. You will learn how to connect web parts in the “Connecting Web Parts” section.
Simple Web Part Tasks
You have already seen that the simplest way to create custom web parts is to create user controls. The only difference is that you add these controls to the ZoneTemplate section of a WebPartZone instead of directly to the page. Basically, the ASP.NET 2.0 Web Parts Framework wraps your user control into an instance of GenericWebPart. This GenericWebPart class makes sure your user control gets the frame and the verbs menu for minimizing and restoring the web part. The same is true for any other server control (either built-in or custom): as long as an ASP.NET control is not inherited from System.Web.UI.WebControls.WebParts.WebPart, the web part framework wraps this control into an instance of GenericWebPart.
If you want to access the properties and events of the controls you have added as web parts to your page, you can do this as you do usually. For example, if you want to catch the Calendar’s SelectedDateChanged event of your previously created web part page, double-click the Calendar. You’ll see your event procedure and can add some code. The following code shows an example that sets the previously added Calendar control’s SelectedDate property on the first request to the page:
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
MyCalendar.SelectedDate = DateTime.Now.AddDays(7);
}
...
}
So, you have complete access to the controls added as web parts and don’t have to do anything special here. But what if you want to access web part–specific properties such as the title of the web part or web part–specific events? As mentioned, every web part that is not inherited from System.Web.UI.WebControls.WebParts.WebPart is wrapped automatically into an instance of GenericWebPart. If you want to access web part–specific properties, you somehow have to retrieve
1056 CHAPTER 31 ■ PORTALS WITH WEB PART PAGES
Table 31-2. Continued
Property |
Description |
ChromeState |
Defines the web part’s initial appearance state. This property is of type |
|
PartChromeState and can have the values Minimized or Normal so that |
|
the WebPart initially is minimized or displayed. |
ConnectErrorMessage |
Specifies the error message that is displayed if an error occurs when |
|
connecting one WebPart to another. |
Controls |
This important collection gives you access to all the controls that are |
|
contained in the web part. You’ll learn more about this immediately |
|
following this table. |
Description |
Specifies a friendly, user-ready description for the web part. |
Direction |
Specifies the content flow direction (LeftToRight or RightToLeft) within |
|
the WebPart. |
DisplayTitle |
Gets a string that returns the title that is actually displayed in the |
|
web part. If you haven’t set the Title property, it returns the either |
|
automatically generated title or the title specified from the containing |
|
control. |
ExportMode |
As you will see later in this chapter, information and settings from |
|
WebParts can be exported and imported. This property specifies which |
|
parts of a web part can be exported or imported. |
HasSharedData |
Specifies whether the WebPart contains personalized properties that |
|
are persisted for multiple users. |
HasUserData |
Specifies whether the WebPart contains personalized properties that |
|
are persisted on a per-user bases. |
HelpUrl |
Through the HelpUrl property you can specify a URL that returns |
|
contents to be displayed as help for the web part. This can point to a |
|
static HTML page or to any other type of page, including an .aspx page. |
|
As soon as this URL is specified, the WebPart displays an additional |
|
verb menu for opening the help of this web part. |
HelpMode |
When a HelpUrl is specified, you can determine where the help is |
|
displayed. The help can be displayed in a modal or modeless pop-up |
|
window, or you can specify to directly navigate to the help page. |
Hidden |
Gets or sets a value that determines whether the WebPart is hidden on |
|
the page. |
IsClosed |
Gets or sets a value that determines whether the WebPart is closed. |
IsShared |
Gets or sets a value that determines whether the WebPart is visible for |
|
all users or for specific users only. You will learn more about this in the |
|
“Authorizing WebParts” section. |
IsStandalone |
Determines whether the WebPart is visible only to a particular user |
|
(true) or to all users (false). |
IsStatic |
Gets or sets a value that determines whether the WebPage is statically |
|
added to the web page through the designer (true) or dynamically |
|
imported to the WebPage. |
Title |
Gets or sets the title to be displayed in the title bar of the web part. |
TitleUrl |
The title can be displayed as URL to point to a details page for the web |
|
part. If this URL is specified, the web part renders the title as a link that |
|
points to this URL instead of static text. |
CHAPTER 31 ■ PORTALS WITH WEB PART PAGES |
1057 |
Property |
Description |
Verbs |
Returns the entries in the web part’s menu that typically contains |
|
the Minimize, Close, or Help verb. You can customize the verbs by |
|
modifying this collection. |
Zone |
Returns a reference to the WebPartZone to which the WebPart is |
|
currently added. |
ZoneIndex |
Returns the WebPartZone’s index to which the WebPart is currently |
|
added. |
|
|
As mentioned in Table 31-2, the Controls collection of the WebPart control contains all the controls hosted within the WebPart. When it comes to the GenericWebPart, this collection contains the controls you have added to the WebPartZone. So, you can iterate through the WebPart controls stored in the Controls collection to find your control and do something with it. The following example shows how you can access the controls of the WebPartPage to set properties of the WebPart that contains the Calendar control added earlier in this chapter:
foreach (WebPart part in MyPartManager.WebParts)
{
if (part.Controls.Contains(MyCalendar))
{
part.AllowClose = false;
part.HelpMode = WebPartHelpMode.Modeless; part.HelpUrl = "CalendarHelp.htm";
}
}
The control added to the WebPartZone is available directly from within the page. Therefore, if you want to set any WebPart-specific properties when loading the page, you can do this the other way around as well. Instead of iterating through the WebPartManager’s WebParts and then accessing every WebPart’s Controls collection, it might be faster to catch the control’s events and then access the WebPart’s properties through the control’s parent property, as follows:
protected void MyCalendar_Load(object sender, EventArgs e)
{
GenericWebPart part = (GenericWebPart)MyCalendar.Parent; part.AllowClose = false;
part.HelpMode = WebPartHelpMode.Modeless; part.HelpUrl = "CalendarHelp.htm";
}
This is definitely faster than searching controls in collections of controls as shown previously. The previous example is doing the same initialization work as shown in the other example: it disables the close function for the WebPart that contains the calendar MyCalendar and then specifies a help page for the calendar that can be displayed in a modeless pop-up browser window. Figure 31-8 shows the result of these modifications. Take a close look at the menu displayed for the WebPart. Because you have initialized the HelpUrl, it now displays an additional Help menu entry. On the other hand, because you have set the AllowClose property to false, it doesn’t contain a Close menu entry anymore.
