Article by Peter Himschoot (peter@u2u.be)
U2U - Brussels (www.u2u.net)
Applies to
- Visual Studio 2005
- ASP.NET 2.0
- C# 2.0
Summary
At TechEd 2005 in Amsterdam I gave a session together with
Andres Sanabria (who is a program manager on Microsoft's .Net Framework team) on
building ASP.NET 2.0 Web Parts. This text explains the demo I gave during this
session. I do not intend to give a full description of everything available for
web parts, but it will give you a nice overview. Some of the web parts are
pre-built, some of the web parts we will build ourselves. After going through
this, you should understand how you can work with web parts, and how you can
build custom web parts.
Please unzip the start.zip file to a directory of your
choosing. Then start Visual Studio 2005, then choose File – Open – Web Site…
Select the directory where you unzipped the start.zip file from your file
system.
Now for an optional part; if you have SQL Express installed
you can skip to setting up the code snippets. However, if you have SQL 2005 CTP
installed, you need to de-install the SQL Express provider and connect to SQL
2005 CTP. This is simple; just add the following to web.config:
<!-- You only need to change the connectionstrings
if you don't have SQL 2005 Express edition
-->
<connectionStrings>
<remove name="LocalSqlServer"/>
<add name="LocalSqlServer"
connectionString="data source=.;Integrated
Security=SSPI;Initial Catalog=ASPNETDB"
providerName="System.Data.SqlClient" />
</connectionStrings>
You will also need to attach the ASPNETDB database in SQL
Server.
This article is accompanied with a web site project and also
with a code snippets file. This will make it a lot easier for you to enter the
code to build the custom web part. To install the code snippet files, first go
to your documents folder where you will find a Code Snippets folder. Drill down
until you reach the My Code Snippets folder and add a new folder called Web
Parts:

Copy the .snippet files to this folder.
Now open the code snippets manager, which you will find
beneath the Tools menu of Visual Studio 2005. Hit the Add button and add the
Web Parts folder. The result should look like this:

Try to run the project. You should get a very simple website
with no actual contents:

Now we are ready to start.
The first thing we need to do to use web parts in a project
is to add the WebPartManager control. Open the Site.Master file in design mode.
Drag the WebPartManager control from to toolbox to the top
left corner of the master file. By adding the WebPartManager control to the
master we will be able to use web parts in all our pages, as long as they use
this master.
Now drag the WebPartPageMenu.ascx control from the project’s
Controls folder to the master page as follows:



Save and close the master page, we don’t need to change it
from now on. You can also find a fill source listing of the master page at the
end of this document.
In this step we added a WebPartManager control to the master
page to enable web parts.
Now open Default.aspx in design mode. Select the content
control, then choose the Layout – Insert Table… menu. Create a custom table
with 1 row and 3 columns. Click the Cell Properties… button to set each cell’s
horizontal align to left, vertical align to top and uncheck the Width checkbox.
Hit Ok twice.
Switch to source view because this will make it easier to
insert a WebPartZone control for the first and second cell. Call the first
WebPartZone LeftZone, and the second one RightZone. Also give them an
appropriate HeaderText. Switch back to design view. Use each WebPartZone’s
smart tag menu to autoformat it to Classic scheme.
In this step we added a table with three columns, and we
added WebPartZone controls to the first two.
Now we can start adding controls to our WebPartZone
controls. Let us start simple by adding the calendar control to the first
WebPartZone. Why not autoformat the calendar while you’re at it?

Run the web site. As you can see, you get a fully functional
web page with one web part. However this web part is actually a wrapper around
the calendar control, and because you don’t see this wrapper, you get a web
part called “Untitled”. However, you can set the title of the wrapper by adding
a Title attribute to your calendar control. Don’t worry about the warning you
will get, this is normal.
Now add the WelcomeWebPart.ascx to the left zone. Don’t
forget to add the Title attribute. Make sure you end up with something looking
like this. Try changing the Display Mode to “Design” and rearrange some of the
webparts.

In this step we added a calendar control and a user control
to our page
The start project also contains a “real” webpart. This is a
class derived from the System.Web.UI. WebControls.WebParts.WebPart base class.
Let us add the webpart to the right zone. Start by registering the web part on
the page (switch to source view):
<%@ Register TagPrefix="Sample"
Namespace="Sample.Web.UI" %>
Then add the web part in a zoneTemplate to the right zone:
<ZoneTemplate>
<Sample:WeatherWebPart ID="weather"
runat="server" />
</ZoneTemplate>
Run the page to see the effect. Again this web part has a
caption set to “Untitled”. To change the caption, change the web parts Title
property, for example:
public WeatherWebPart()
{
this.Title = "Weather";
}
Now we get:

Now let’s add some support to allow us to edit web part’s
properties. Start by adding a EditorZone to the third column (again use source view):
<td align="left"
valign="top">
<asp:EditorZone ID="EditorZone1"
runat="server">
</asp:EditorZone>
</td>
Then switch to design view, do an Auto Format… to Classic,
and add an AppearanceEditorPart and PropertyGridEditorPart. Your EditorZone
should now look like this

Run the application again. Change the page’s display mode to
Edit, and then select the Edit verb from the web part’s menu. The Editor Zone
is now visible and you should be able to change the web part’s appearance and
ZipCode property. For example, try setting the zipcode to 98052 to see the
weather in Redmond, Seattle.

In this step we added a web part to our page.
As we saw previously, you can add any control as a web
control. Now we will create a simple user control and then add special web part
support to it. Start by adding a new item to the project, and selecting Web
User Control. Keep the default name of WebUserControl.ascx and click Add.
Now add a TextBox control to your new user control:
<%@ Control Language="C#"
AutoEventWireup="true"
CodeFile="WebUserControl.ascx.cs"
Inherits="WebUserControl" %>
<asp:TextBox ID="TextBox1"
runat="server">
</asp:TextBox>
That is all we need to do to add the control as a web part,
so add the new control to the right zone inside the ZoneTemplate using the
designer:
<uc2:WebUserControl
ID="WebUserControl1" runat="server" />
Run the project to see if the user control is actually part
of the page. Please note that our web part again has an “Untitled” caption.
Now let’s add special web part support by implementing the
IWebPart interface. Switch to the web part’s code view and add the IWebPart
interface to the class:
public partial class WebUserControl
: System.Web.UI.UserControl
, IWebPart
Use the IWebPart code snippet to implement the interface. If
you’ve never worked with code snippets, right-click your code, and select
Insert Snippet… Then select My Code Snippets, followed by Web Parts, then
IWebPart.
// add the IWebPart interface to the class
private string _catalogImageUrl = string.Empty;
private string _description = string.Empty;
private string _subTitle = "[0]";
private string _title = "Super cool user
control ";
public string CatalogIconImageUrl
{
get { return _catalogImageUrl; }
set { _catalogImageUrl = value; }
}
public string Description
{
get { return _description; }
set { _description = value; }
}
public string Subtitle
{
get { return _subTitle; }
set { _subTitle = value; }
}
public string Title
{
get { return _title; }
set { _title = value; }
}
public string TitleIconImageUrl
{
get { return string.Empty; }
set { ; }
}
public string TitleUrl
{
get { return string.Empty; }
set { ; }
}
Change some of the properties to see the effect. For
example, change the TitleIconImageUrl to:
public string TitleIconImageUrl
{
get { return "~/Images/detail.gif"; }
set { ; }
}
Run the application to see your user control with a nice
icon in the web part’s title bar:

In this step we created a user control, hosted it as a web
part inside a zone, and added support to the user control for the web part
infrastructure by implementing the IWebPart interface.
Right-click the App_Code folder and select Add New Item…
Select the Class template and name it TextDisplayWebPart. Select the class’s
code and replace it with the TextDisplayWebPart code snippet.
using …
namespace Sample.WebParts
{
public class TextDisplayWebPart : WebPart
{ }
}
This is now a very simple web part, but of course to make it
do something usefull we need to add and override some properties. Use the
TextDisplayWebPart properties code snippet to add the following code:
private string _ContentText = "foo";
public TextDisplayWebPart()
{
this.AllowClose = false;
this.Title = "Text Display (ASP.NET)
:)";
}
public string ContentText
{
get { return _ContentText; }
set { _ContentText = value; }
}
public override bool AllowClose
{
get { return false; }
set {/*base.AllowClose = value;*/}
}
public override bool AllowMinimize
{
get { return false; }
set {/*base.AllowClose = value;*/}
}
This code adds the ContentText property, which will be
displayed by the web part. We also override the AllowClose and AllowMinimize
properties to hide the Close and Minimize verbs.
New let’s create the child controls that will be used by the
web part. We do this by overriding the CreateChildControls method. Insert the
code using the TextDisplayWebPart code snippet:
Label DisplayContent;
protected override void CreateChildControls()
{
Controls.Clear();
DisplayContent = new Label();
DisplayContent.Text = this.ContentText;
this.Controls.Add(DisplayContent);
ChildControlsCreated = true;
}
This code simply creates a label to display the content. At
the end of the method we let the web part know that it has been properly
initialized by setting the ChildControlsCreated property to true.
Ok, this web part is now ready to be used on our page, so
register the web part:
<%@ Register TagPrefix="Sample"
Namespace="Sample.WebParts" %>
And add it the right zone:
<Sample:TextDisplayWebPart
id="display" runat="server" />
Run the page. In this step we created a custom web part by
deriving from the WebPart base class and overriding some of its properties and
methods.
Every web part has a bunch of verbs users can select. We can
easily add our own custom verbs, simply by overriding the Verbs property. Add
the code using the TextDisplayWebPart Verbs snippet.
public override WebPartVerbCollection Verbs
{
get
{
EnsureChildControls();
WebPartVerb saveVerb =
new WebPartVerb("SaveVerb", new
WebPartEventHandler(SaveData));
saveVerb.Text = "Save";
WebPartVerb[] newVerbs = new WebPartVerb[] {
saveVerb };
WebPartVerbCollection wp =
new WebPartVerbCollection(base.Verbs,
newVerbs);
return wp;
}
}
public void SaveData(object sender,
WebPartEventArgs args)
{
EnsureChildControls();
this.Title = this.Title + " Saved ..";
}
The Verbs property returns a WebPartVerbCollection instance,
which we fill with a single WebPartVerb object. The WebPartVerb constructor
takes a name and WebPartEventHandler as arguments. This WebPartEventHandler
gets called when the user selects the verb from the web part’s menu. In this
case the verb will execute the SaveData method, which simply appends “Saved …”
to the web parts caption.
In this step we added custom verbs so our users can easily
execute commands on the web parts.
Our user control web part and our custom web part can now be
personalized. This means that the end user can change properties of the web
part. For example, to allow the user to change the Subtitle property of the
WebUserControl.ascx control, we add the Personalizable and WebBrowsable
attributes to the property (use the Enable property editing snippet):
[Personalizable()]
[WebBrowsable()]
public string Subtitle
{
get { return _subTitle; }
set { _subTitle = value; }
}
The Personalizable attribute will store this property in the
Personalization store, and the WebBrowsable attribute enables editing the property
in the EditorZone.
If you need more control, like setting the EditorZone’s
caption and tooltip for the property, you can add the WebDisplayName and
WebDescription attributes. For example, let’s add these attributes to the
WeatherWebPart ZipCode property (use the More property editing snippet):
[Personalizable]
[WebBrowsable]
[WebDisplayName("City Zip Code")]
[WebDescription("Enter City Zip Code")]
public string ZipCode
{...}
Run the page, set the page’s display mode to Edit, and use
the Edit verb to see the EditorZone and the attributes their effect.
In this step we added personalization and browsing support
to our web part’s properties.
Another nice feature of using web parts is that we can have
a bunch of web parts that are not displayed immediately through a catalog. The
catalog can hold web parts that were closed by the user and also web parts that
optionally can be added. Let’s start by adding a CatalogZone to the third
column of our table (If you want to collapse the editor zone, you can check the
View in Browse Mode checkbox from the editor zone’s smart tag menu.). Auto
Format it to Classic, and then add the PageCatalogPart and DeclarativeCatalogPart
controls:

When you the display mode to Catalog, the PageCatalogPart
will display any closed web parts, allowing the user to re-add these. The
DeclarativeCatalogPart will display any additional web parts the developer or
admin provided for this page. So before we run this page to see this, let’s add
a couple of extra web parts to the DeclarativeCatalogPart. To do this, select
Edit Templates from the web parts smart tag menu. Drag the
AnnouncementsWebPart.ascx and DailyLinksWebPart.ascx controls from the Controls
folder onto the template. Give them a nice Title attribute in Source view:
<asp:DeclarativeCatalogPart
ID="DeclarativeCatalogPart1" runat="server">
<WebPartsTemplate>
<uc3:AnnouncementsWebPart
Title="Announcements"
ID="AnnouncementsWebPart1"
runat="server" />
<uc4:DailyLinksWebPart Title="Daily
Links"
ID="DailyLinksWebPart1" runat="server"
/>
</WebPartsTemplate>
Run the page. Set the page’s display mode to Design and
close the Calander web part with its Close verb. Now set the page’s display
mode to Catalog to see the Catalog Zone:

If you want, you can now re-add the Calendar web part to any
zone using the Add button. Now click the Declarative Catalog (2) link:

As you can see, you can now add an Announcements and/or
Daily Links web part to any zone using the Add button.
In this step we added a CatalogZone to allow our users to
add other web parts to the page.
The catalog doesn’t stop here. You can export and import web
parts settings from other pages or even other web sites. First let’s export a
web part. To do this we need to explicitly allow a web part to be exported by
setting its ExportMode property to true (Export Web Part snippet). Insert this
snippet in the TextDisplayWebPart constructor:
public TextDisplayWebPart()
{
this.AllowClose = false;
this.Title = "Text Display (ASP.NET)
:)";
this.ExportMode = WebPartExportMode.All;
}
We also need to enable exporting web parts on our web site
itself by editing the web.config file:
<webParts enableExport="true">
<personalization>
<authorization>
<allow users="*"
verbs="enterSharedScope"/>
</authorization>
</personalization>
</webParts>
Now when we start our web site, web parts that are
exportable will have an extra Export verb. If you choose this verb, you will be
able to save the web part’s settings to a .WebPart file.

Once you have exported web parts, you can import them back
again on the same page or another using the ImportCatalogPart. So to try this,
we first add the ImportCatalogPart to the CatalogZone on our page. Now run the
page and change the display mode to Catalog. Click on the Imported Web Part
Catalog(0) link which displays the Imported Web Part Catalog. Click the Browse…
button to open a exported web part file, then click the Upload button. The
imported web part should be displayed, ready to be added to one of the zones.

In this step we exported a web part, then imported the
settings back using the Imported Web Part Catalog.
One of the coolest features of using Web parts is connection
two web parts together, for example you could have one web part allowing you to
select a zipcode, and having other web parts use that zipcode to display
information about the weather, draw a little map, etc… Connecting web parts is
actually quite simple, the first thing you need is an interface that describes
what kind of data or behavior flows between the consumer and provider web part.
We will connect our user control to our custom web control. When someone enters
text into the user control, the custom web control will display this text. So
the data that will flow between the two web parts is a piece of text.
Let us add an interface with one text property. Add a new
item to the App_Code folder and call it ITextCommunication. Now use the
ITextCommunication snippet to implement the interface:
namespace Sample.WebParts
{
public interface ITextCommunication
{
string Text { get;}
}
}
This interface has a simple Text property.
The provider control implements this interface, so add the
ITextCommunication to the WebUserControl.ascx control:
using Sample.WebParts;
public partial class WebUserControl
: System.Web.UI.UserControl
, IWebPart
, ITextCommunication
{...}
And implement the Text property using the ConnectionProvider
snippet:
string ITextCommunication.Text
{
get { return this.TextBox1.Text; }
}
[ConnectionProvider("TextProvider",
"Text Provider")]
public ITextCommunication
ProvideInterfaceForConnection()
{
return this;
}
Implementing the consumer side for a connection is just as
simple; we need to get a reference to this interface so we add a method with
the ConnectionConsumer attribute (using the ConnectionConsumer code snippet).
ITextCommunication _provider;
[ConnectionConsumer("TextConsumer1",
"test Consumer")]
public void GetItextProvider(Sample.WebParts.ITextCommunication
myInterface)
{
if (myInterface != null)
_provider = myInterface;
}
protected override void OnPreRender(EventArgs e)
{
if (_provider != null)
{
ContentText = _provider.Text;
if (!String.IsNullOrEmpty(ContentText))
{
DisplayContent.Text = ContentText;
}
}
}
We also override the OnPreRender method to check for the
availability of this interface, and if so, use the Text property to set the
contents of the web part.
Before we run the sample, we also need to add a
ConnectionZone to the third column in the table on our page. When running,
change the display mode to Connect. This will add a Connect verb to every
connectable web part. So choose the Connect verb of either the WebUserControl
or the TextDisplayWebPart control. This will display the ConnectZone allowing
you to choose a matching Provider or Consumer web part:

Click the Connect button. Now we have two connected web
parts:

In this step we connected two web parts dynamically. You can
also connect web parts statically using the WebPartManager control.
Peter
Himschoot is an architect and trainer for U2U, specializing in .NET
development, Visual Studio Team System and BizTalk. He is also a Microsoft
Regional Director (http://www.microsoft.com/belux/nl/msdn/community/regionaldir.mspx
).
You can reach him at peter@u2u.net.
U2U
Training and Consultancy Services is a Microsoft .NET competence center located
in Belgium, to learn more please visit www.u2u.be
.
<%@ Master Language="C#" %>
<%@ Register
Src="Controls/WebPartPageMenu.ascx"
TagName="WebPartPageMenu"
TagPrefix="uc1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML
4.01 Transitional//EN">
<html>
<head runat="server">
<title>ASP.NET Intranet
Portal</title>
<link type="text/css"
rel="stylesheet" href="StyleSheet.css">
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
</head>
<body leftmargin="0"
topmargin="0" marginwidth="0"
marginheight="0">
<form id="form1"
runat="server">
<asp:WebPartManager
ID="WebPartManager1" runat="server">
</asp:WebPartManager>
<table width="100%"
height="100%" border="0"
cellpadding="0"
cellspacing="0">
<tr height="1%">
<td colspan="3">
<table width="100%"
height="100%" border="0"
cellpadding="0"
cellspacing="0">
<tr
class="BannerFrame">
<td>
</td>
<td class="BannerCell"
style="width: 99%">
<asp:DataList
ID="DataList1" runat="server"
DataSourceID="SiteMapDataSource1"
RepeatDirection="Horizontal"
CssClass="BannerCell"
RepeatLayout="Flow">
<SeparatorTemplate>
|
</SeparatorTemplate>
<ItemTemplate>
<asp:HyperLink
ID="Hyperlink3" runat="server"
NavigateUrl='<%#
Eval("Url") %>'
Text='<%#
Eval("Title") %>' />
</ItemTemplate>
</asp:DataList>
</td>
<td class="BannerCell"
nowrap="nowrap">
<asp:LoginName
ID="LoginName1" runat="server" />
</td>
<td>
</td>
</tr>
</table>
</td>
</tr>
<tr height="3px"
class="HeaderFrame">
<td colspan="3">
<asp:Image ID="Image2"
runat="Server"
ImageUrl="~/images/yellow.GIF" Width="100%"
Height="3px" /></td>
</tr>
<tr height="49px">
<td width="80px">
<p align="center">
<asp:HyperLink
ID="HyperLink2"
NavigateUrl="~/default.aspx"
runat="server">
<asp:Image
runat="server"
ImageUrl="~\Images/U2U%20logo%2050x50%20pixs.JPG"
/>
</asp:HyperLink>
</p>
</td>
<td class="HeaderCell">
<font
color="#000000">U2U</font>
<br />
<span
class="HeaderTitle">Home </span>
</td>
<td nowrap="nowrap"
class="HeaderCell" align="right">
<p>
<uc1:WebPartPageMenu
ID="WebPartPageMenu1" runat="server" />
</p>
</td>
</tr>
<tr height="1px"
class="HeaderFrame">
<td colspan="3">
<asp:Image ID="Image1" runat="Server"
ImageUrl="~/images/yellow.GIF" Width="100%"
Height="1px" /></td>
</tr>
<tr height="99%">
<td class="LightBlueTable"
valign="top" width="80px">
<br />
<table>
<tr>
<td width="5px">
</td>
<td>
<asp:DataList
ID="TopLinksDataList" runat="server"
DataSourceID="TopLinksDatasetdatasource">
<ItemTemplate>
<asp:HyperLink
ID="HyperLink1" Font-Bold="true"
runat="server"
Text='<%# Eval("title") %>'
NavigateUrl='<%#
Eval("url") %>'
CssClass="BulletStyle" />
</ItemTemplate>
</asp:DataList>
<asp:XmlDataSource
ID="TopLinksDatasetdatasource"
runat="server"
XPath="/links/link"
DataFile="~/app_data/toplinks.xml"
/>
</td>
</tr>
</table>
</td>
<td valign="top"
align="left" colspan="3" style="width: 99%">
<div align="left">
<asp:ContentPlaceHolder
ID="MiddleContent" runat="server">
</asp:ContentPlaceHolder>
</div>
<p align="left">
</p>
</td>
</tr>
<tr>
<td class="LightBlueTable"
height="40" style="width: 18%">
</td>
<td style="width: 78%">
</td>
<td style="width: 49%">
</td>
</tr>
</table>
<asp:SiteMapDataSource
ID="SiteMapDataSource1" runat="server" />
</form>
</body>
</html>
<%@ Page SmartNavigation="false"
Language="C#"
MasterPageFile="~/Site.master" %>
<%@ Register Src="Controls/AnnouncementsWebPart.ascx"
TagName="AnnouncementsWebPart" TagPrefix="uc3"
%>
<%@ Register
Src="Controls/DailyLinksWebPart.ascx"
TagName="DailyLinksWebPart"
TagPrefix="uc4" %>
<%@ Register
Src="Controls/WebUserControl.ascx" TagName="WebUserControl"
TagPrefix="uc2" %>
<%@ Register
Src="Controls/WelcomeWebPart.ascx" TagName="WelcomeWebPart"
TagPrefix="uc1" %>
<%@ Register TagPrefix="Sample"
Namespace="Sample.Web.UI" %>
<%@ Register TagPrefix="Sample"
Namespace="Sample.WebParts" %>
<asp:Content ID="MiddleContent"
ContentPlaceHolderID="MiddleContent"
runat="server">
<table>
<tr>
<td align="left"
valign="top">
<asp:WebPartZone ID="LeftZone"
runat="server" HeaderText="Left Zone"
BorderColor="#CCCCCC" Font-Names="Verdana"
Padding="6">
<PartChromeStyle
BackColor="#EFF3FB" BorderColor="#D1DDF1"
Font-Names="Verdana"
ForeColor="#333333" />
<MenuLabelHoverStyle
ForeColor="#D1DDF1" />
<EmptyZoneTextStyle
Font-Size="0.8em" />
<MenuLabelStyle
ForeColor="White" />
<MenuVerbHoverStyle
BackColor="#EFF3FB" BorderColor="#CCCCCC"
BorderStyle="Solid"
BorderWidth="1px" ForeColor="#333333" />
<HeaderStyle
Font-Size="0.7em" ForeColor="#CCCCCC"
HorizontalAlign="Center"
/>
<MenuVerbStyle
BorderColor="#507CD1" BorderStyle="Solid"
BorderWidth="1px"
ForeColor="White" />
<PartStyle Font-Size="0.8em"
ForeColor="#333333" />
<TitleBarVerbStyle Font-Size="0.6em"
Font-Underline="False"
ForeColor="White" />
<MenuPopupStyle
BackColor="#507CD1" BorderColor="#CCCCCC"
BorderWidth="1px"
Font-Names="Verdana" Font-Size="0.6em" />
<PartTitleStyle
BackColor="#507CD1" Font-Bold="True"
Font-Size="0.8em"
ForeColor="White" />
<ZoneTemplate>
<asp:Calendar
Title="Calendar" ID="Calendar1" runat="server"
BackColor="White"
BorderColor="#3366CC"
BorderWidth="1px" CellPadding="1"
DayNameFormat="Shortest"
Font-Names="Verdana"
Font-Size="8pt" ForeColor="#003399"
Height="200px"
Width="220px">
<SelectedDayStyle
BackColor="#009999" Font-Bold="True"
ForeColor="#CCFF99" />
<SelectorStyle
BackColor="#99CCCC" ForeColor="#336666" />
<WeekendDayStyle
BackColor="#CCCCFF" />
<OtherMonthDayStyle
ForeColor="#999999" />
<TodayDayStyle
BackColor="#99CCCC" ForeColor="White" />
<NextPrevStyle
Font-Size="8pt" ForeColor="#CCCCFF" />
<DayHeaderStyle
BackColor="#99CCCC" ForeColor="#336666"
Height="1px" />
<TitleStyle
BackColor="#003399" BorderColor="#3366CC"
BorderWidth="1px"
Font-Bold="True"
Font-Size="10pt"
ForeColor="#CCCCFF" Height="25px" />
</asp:Calendar>
<uc1:WelcomeWebPart
Title="Welcome" ID="WelcomeWebPart1"
runat="server" />
</ZoneTemplate>
</asp:WebPartZone>
</td>
<td align="left"
valign="top">
<asp:WebPartZone
ID="RightZone" runat="server"
HeaderText="Right Zone"
BorderColor="#CCCCCC" Font-Names="Verdana"
Padding="6">
<PartChromeStyle
BackColor="#EFF3FB" BorderColor="#D1DDF1"
Font-Names="Verdana"
ForeColor="#333333" />
<MenuLabelHoverStyle
ForeColor="#D1DDF1" />
<EmptyZoneTextStyle
Font-Size="0.8em" />
<MenuLabelStyle
ForeColor="White" />
<MenuVerbHoverStyle
BackColor="#EFF3FB" BorderColor="#CCCCCC"
BorderStyle="Solid"
BorderWidth="1px"
ForeColor="#333333" />
<HeaderStyle
Font-Size="0.7em" ForeColor="#CCCCCC"
HorizontalAlign="Center"
/>
<MenuVerbStyle
BorderColor="#507CD1" BorderStyle="Solid"
BorderWidth="1px"
ForeColor="White" />
<PartStyle Font-Size="0.8em"
ForeColor="#333333" />
<TitleBarVerbStyle
Font-Size="0.6em" Font-Underline="False"
ForeColor="White" />
<MenuPopupStyle
BackColor="#507CD1" BorderColor="#CCCCCC"
BorderWidth="1px"
Font-Names="Verdana"
Font-Size="0.6em" />
<PartTitleStyle
BackColor="#507CD1" Font-Bold="True"
Font-Size="0.8em"
ForeColor="White" />
<ZoneTemplate>
<Sample:WeatherWebPart
ID="weather" runat="server"
Title="Weather"
ZipCode="" />
<uc2:WebUserControl
ID="WebUserControl1" runat="server" />
<Sample:TextDisplayWebPart
ID="display" runat="server" />
</ZoneTemplate>
</asp:WebPartZone>
</td>
<td align="left"
valign="top">
<asp:EditorZone
ID="EditorZone1" runat="server"
BackColor="#EFF3FB"
BorderColor="#CCCCCC"
BorderWidth="1px" Font-Names="Verdana"
Padding="6">
<LabelStyle
Font-Size="0.8em" ForeColor="#333333" />
<HeaderStyle
BackColor="#D1DDF1" Font-Bold="True"
Font-Size="0.8em"
ForeColor="#333333" />
<ZoneTemplate>
<asp:AppearanceEditorPart
ID="AppearanceEditorPart1"
runat="server" />
<asp:PropertyGridEditorPart
ID="PropertyGridEditorPart1"
runat="server" />
</ZoneTemplate>
<HeaderVerbStyle
Font-Bold="False" Font-Size="0.8em"
Font-Underline="False"
ForeColor="#333333" />
<PartChromeStyle
BorderColor="#D1DDF1" BorderStyle="Solid"
BorderWidth="1px" />
<PartStyle BorderColor="#EFF3FB"
BorderWidth="5px" />
<FooterStyle
BackColor="#D1DDF1" HorizontalAlign="Right" />
<EditUIStyle
Font-Names="Verdana" Font-Size="0.8em"
ForeColor="#333333" />
<InstructionTextStyle
Font-Size="0.8em" ForeColor="#333333" />
<ErrorStyle
Font-Size="0.8em" />
<VerbStyle
Font-Names="Verdana" Font-Size="0.8em"
ForeColor="#333333" />
<EmptyZoneTextStyle
Font-Size="0.8em" ForeColor="#333333" />
<PartTitleStyle Font-Bold="True"
Font-Size="0.8em"
ForeColor="#333333" />
</asp:EditorZone>
<asp:CatalogZone
ID="CatalogZone1" runat="server"
BackColor="#EFF3FB"
BorderColor="#CCCCCC"
BorderWidth="1px"
Font-Names="Verdana" Padding="6">
<HeaderVerbStyle
Font-Bold="False" Font-Size="0.8em"
Font-Underline="False"
ForeColor="#333333" />
<PartTitleStyle
BackColor="#507CD1" Font-Bold="True" Font-
Size="0.8em"
ForeColor="White" />
<FooterStyle
BackColor="#D1DDF1" HorizontalAlign="Right" />
<PartChromeStyle
BorderColor="#D1DDF1" BorderStyle="Solid"
BorderWidth="1px" />
<InstructionTextStyle
Font-Size="0.8em" ForeColor="#333333" />
<LabelStyle
Font-Size="0.8em" ForeColor="#333333" />
<ZoneTemplate>
<asp:PageCatalogPart
ID="PageCatalogPart1" runat="server" />
<asp:DeclarativeCatalogPart
ID="DeclarativeCatalogPart1"
runat="server">
<WebPartsTemplate>
<uc3:AnnouncementsWebPart
Title="Announcements"
ID="AnnouncementsWebPart1"
runat="server" />
<uc4:DailyLinksWebPart
Title="Daily Links"
ID="DailyLinksWebPart1"
runat="server" />
</WebPartsTemplate>
</asp:DeclarativeCatalogPart>
<asp:ImportCatalogPart
ID="ImportCatalogPart1" runat="server" />
</ZoneTemplate>
<PartLinkStyle
Font-Size="0.8em" />
<SelectedPartLinkStyle
Font-Size="0.8em" />
<VerbStyle
Font-Names="Verdana" Font-Size="0.8em"
ForeColor="#333333" />
<HeaderStyle
BackColor="#D1DDF1" Font-Bold="True" Font-
Size="0.8em"
ForeColor="#333333" />
<EmptyZoneTextStyle
Font-Size="0.8em" ForeColor="#333333" />
<EditUIStyle
Font-Names="Verdana" Font-Size="0.8em"
ForeColor="#333333" />
<PartStyle
BorderColor="#EFF3FB" BorderWidth="5px" />
</asp:CatalogZone>
<asp:ConnectionsZone
ID="ConnectionsZone1" runat="server"
BackColor="#EFF3FB"
BorderColor="#CCCCCC"
BorderWidth="1px"
Font-Names="Verdana" Padding="6">
<FooterStyle
BackColor="#D1DDF1" HorizontalAlign="Right" />
<VerbStyle
Font-Names="Verdana" Font-Size="0.8em"
ForeColor="#333333" />
<InstructionTextStyle
Font-Size="0.8em" ForeColor="#333333" />
<EditUIStyle
Font-Names="Verdana" Font-Size="0.8em"
ForeColor="#333333" />
<LabelStyle
Font-Size="0.8em" ForeColor="#333333" />
<HeaderStyle
BackColor="#D1DDF1" Font-Bold="True"
Font-Size="0.8em"
ForeColor="#333333" />
<HeaderVerbStyle
Font-Bold="False" Font-Size="0.8em" Font-
Underline="False"
ForeColor="#333333" />
</asp:ConnectionsZone>
</td>
</tr>
</table>
</asp:Content>
// U2U - Microsoft Certified Training Center
// Sample by Peter Himschoot, peter@u2u.be
// Please let me know what you think!
// Copyright 2005 U2U Belgium, www.u2u.net
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
namespace Sample.WebParts
{
public interface ITextCommunication
{
string Text { get;}
}
}
<%@ Control Language="C#"
AutoEventWireup="true"
CodeFile="WebUserControl.ascx.cs"
Inherits="WebUserControl" %>
<asp:TextBox ID="TextBox1"
runat="server"></asp:TextBox>
// U2U - Microsoft Certified Training Center
// Sample by Peter Himschoot, peter@u2u.be
// Please let me know what you think!
// Copyright 2005 U2U Belgium, www.u2u.net
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Sample.WebParts;
public partial class WebUserControl
: System.Web.UI.UserControl
, IWebPart
, ITextCommunication
{
string ITextCommunication.Text
{
get { return this.TextBox1.Text; }
}
[ConnectionProvider("TextProvider",
"Text Provider")]
public ITextCommunication
ProvideInterfaceForConnection()
{
return this;
}
protected void Page_Load(object sender, EventArgs
e)
{
}
// add the IWebPart interface to the class
private string _catalogImageUrl = string.Empty;
private string _description = string.Empty;
private string _subTitle = "[0]";
private string _title = "Super cool user
control ";
public string CatalogIconImageUrl
{
get { return _catalogImageUrl; }
set { _catalogImageUrl = value; }
}
public string Description
{
get { return _description; }
set { _description = value; }
}
[Personalizable()]
[WebBrowsable()]
public string Subtitle
{
get { return _subTitle; }
set { _subTitle = value; }
}
public string Title
{
get { return _title; }
set { _title = value; }
}
public string TitleIconImageUrl
{
get { return "~/Images/detail.gif"; }
set { ; }
}
public string TitleUrl
{
get { return string.Empty; }
set { ; }
}
}
// U2U - Microsoft Certified Training Center
// Sample by Peter Himschoot, peter@u2u.be
// Please let me know what you think!
// Copyright 2005 U2U Belgium, www.u2u.net
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
namespace Sample.WebParts
{
public class TextDisplayWebPart : WebPart
{
private string _ContentText = "foo";
public TextDisplayWebPart()
{
this.AllowClose = false;
this.Title = "Text Display (ASP.NET)
:)";
this.ExportMode = WebPartExportMode.All;
}
public string ContentText
{
get { return _ContentText; }
set { _ContentText = value; }
}
public override bool AllowClose
{
get { return false; }
set {/*base.AllowClose = value;*/}
}
public override bool AllowMinimize
{
get { return false; }
set {/*base.AllowClose = value;*/}
}
Label DisplayContent;
protected override void CreateChildControls()
{
Controls.Clear();
DisplayContent = new Label();
DisplayContent.Text = this.ContentText;
this.Controls.Add(DisplayContent);
ChildControlsCreated = true;
}
public override WebPartVerbCollection Verbs
{
get
{
EnsureChildControls();
WebPartVerb saveVerb = new
WebPartVerb("SaveVerb", new WebPartEventHandler(SaveData));
saveVerb.Text = "Save";
WebPartVerb[] newVerbs = new WebPartVerb[]
{ saveVerb };
WebPartVerbCollection wp = new
WebPartVerbCollection(base.Verbs, newVerbs);
return wp;
}
}
public void SaveData(object sender, WebPartEventArgs
args)
{
EnsureChildControls();
this.Title = this.Title + " Saved
..";
}
ITextCommunication _provider;
[ConnectionConsumer("TextConsumer1",
"test Consumer")]
public void
GetItextProvider(Sample.WebParts.ITextCommunication myInterface)
{
if (myInterface != null)
_provider = myInterface;
}
protected override void OnPreRender(EventArgs
e)
{
if (_provider != null)
{
ContentText = _provider.Text;
if (!String.IsNullOrEmpty(ContentText))
{
DisplayContent.Text = ContentText;
}
}
}
}
}