An example of this scenario is illustrated in Figure 17-24.WEB PAGE WEB PART ZONE 1 WEB PART ZONE 2 PROVIDER WEB PART PROVIDER WEB PART CONSUMER WEB PART CONSUMER WEB PART Figure 17-24 F
Trang 1Literal LineBreak = new Literal();
LineBreak.Text = "<br />";
Controls.Add(LineBreak);
Controls.Add(StateInput);
Button InputButton = new Button();
InputButton.Text = "Input State";
InputButton.Click += this.Button1_Click;
Controls.Add(InputButton);
Literal Spacer = new Literal();
Spacer.Text = "<p>";
Controls.Add(Spacer);
Controls.Add(StateContents);
ChildControlsCreated = true;
}
private void Button1_Click(object sender, EventArgs e)
{
StateContents.Items.Add(StateInput.Text);
StateInput.Text = String.Empty;
StateInput.Focus();
}
}
}
To review, you first import theSystem.Web.UI.WebControls.WebPartsnamespace The important step
in the creation of this custom control is to make sure that it inherits from theWebPartclass instead of the customaryControlclass As stated earlier, this gives the control access to the advanced functionality of the Portal Framework that a typical custom control would not have
VB
Public Class StateListBox
Inherits WebPart
End Class
C#
public class StateListBox : WebPart
{
}
After the class structure is in place, a few properties are defined, and the constructor is defined as well The constructor directly uses some of the capabilities that theWebPartclass provides These capabilities would not be available if this custom control has theControlclass as its base class and is making use of theWebPart.AllowCloseproperty
Trang 2Public Sub New()
Me.AllowClose = False
End Sub
C#
public StateListBox()
{
AllowClose = false;
}
This constructor creates a control that explicitly sets the control’sAllowCloseproperty toFalse—
mean-ing that the Web Part will not have a Close link associated with it when generated in the page Because
of the use of theWebPartclass instead of theControlclass, you will find, in addition to the
Allow-Closeproperty, otherWebPartclass properties such asAllowEdit,AllowHide,AllowMinimize,
Allow-ZoneChange, and more
In the example shown in Listing 17-14, you see a custom-defined property:LabelStartText This
prop-erty allows the developer to change the instruction text displayed at the top of the control The big
difference with this custom property is that it is preceded by thePersonalizableand theWebBrowsable
attributes
ThePersonalizableattribute enables the property for personalization, whereas theWebBrowsable
attribute specifies whether the property should be displayed in the Properties window in Visual
Stu-dio ThePersonalizableattribute can be defined further using aPersonalizationScopeenumeration
The only two possible enumerations —SharedandUser— can be defined in the following ways:
VB
<Personalizable(PersonalizationScope.Shared), WebBrowsable()> _
Public Property LabelStartText() As String
Get
Return _LabelStartText
End Get
Set(ByVal value As String)
_LabelStartText = value
End Set
End Property
C#
[Personalizable(PersonalizationScope.Shared), WebBrowsable]
public String LabelStartText
{
get { return _LabelStartText; }
set { _LabelStartText = value; }
}
APersonalizationScopeofUsermeans that any modifications are done on a per-user basis This is the
default setting and means that if a user makes modifications to the property, the changes are seen only
by that particular user and not by the other users that browse the page If thePersonalizationScopeis
set toShared, changes made by one user can be viewed by others requesting the page
Trang 3After you have any properties in place, the next step is to define what gets rendered to the page by over-riding theCreateChildControlsmethod From the example in Listing 17-14, theCreateChildControls
method renders Label, Literal, TextBox, Button, and ListBox controls In addition to defining the proper-ties of some of these controls, a single event is associated with the Button control (Button1_Click) that is also defined in this class
Now that the custom Web Part control is in place, build the project so that a DLL is created The next
step is to open up the ASP.NET Web project where you want to utilize this new control and, from the
Visual Studio Toolbox, add the new control You can quickly accomplish this task by right-clicking in
the Toolbox on the tab where you want the new control to be placed After right-clicking the appropriate tab, select Choose Items Click the Browse button and point to the newMyStateListBox.dllthat you
just created After this is done, the StateListBox control is highlighted and checked in the Choose Toolbox Items dialog, as illustrated in Figure 17-22
Figure 17-22
Clicking OK adds the control to your Toolbox Now you are ready to use this new control as a Web Part control To do this, simply drag and drop the control into one of your Web Part Zone areas This does a couple of things First, it registers the control on the page using the Register directive:
<%@ Register TagPrefix="cc1" Namespace="MyStateListBox.Wrox"
Assembly="MyStateListBox" %>
Trang 4Once registered, the control can be used on the page If dragged and dropped onto the page’s design
surface, you get a control in the following construct:
<cc1:StateListBox Runat="server" ID="StateListBox1"
LabelStartText=" Enter State Name: " AllowClose="False" />
The two important things to notice with this construct is that the custom property,LabelStartText, is
present and has the default value in place, and theAllowCloseattribute is included TheAllowClose
attribute is present only because earlier you made the control’s inherited classWebPartand notControl
BecauseWebPartwas made the inherited class, you have access to these Web Part–specific properties
When the StateListBox control is drawn on the page, you can see that, indeed, it is part of the larger Portal
Framework and allows for things such as minimization and editing End users can use this custom Web
Part control as if it were any other type of Web Part control As you can see, you have a lot of power
when you create your own Web Part controls
And becauseLabelStartTextuses theWebBrowsableattribute, you can use the PropertyGridEditorPart
control to allow end users to edit this directly in the browser With this in place, as was demonstrated
earlier in Listing 17-5, an end user will see the following editing capabilities after switching to the Edit
mode (see Figure 17-23)
Figure 17-23
Connecting Web Par ts
In working with Web Parts, you sometimes need to connect them in some fashion Connecting them
means that you must pass a piece of information (an object) from one Web Part to another Web Part on
the page
For instance, you might want to transfer the text value (such as a zip code or a name) that someone enters
in a text box to other Web Parts in the page Another example is a DropDownList control that specifies all
the available currencies in the system If the end user selects from the drop-down list, this drives changes
in all the other Web Parts on that page that deal with this currency value selection When you need to
build constructions in this manner, you can use the Web Part connection capabilities defined here, or you
might be able to work with other ASP.NET systems available (such as the personalization capabilities
provided through the profile system)
When connecting Web Parts, you should be aware of the specific rules on how these Web Parts interact
with one another First off, if you want to make a connection from one Web Part to another, one of
the Web Parts must be the provider This provider Web Part is the component that supplies the piece
of information required by any other Web Parts The Web Parts that require this information are the
consumer Web Parts A Web Part provider can supply information to one or more consumer Web Parts;
however, a consumer Web Part can only connect with a single provider Web Part You cannot have a
consumer Web Part that connects to more than one provider Web Part
Trang 5An example of this scenario is illustrated in Figure 17-24.
WEB PAGE WEB PART ZONE 1 WEB PART ZONE 2
PROVIDER WEB PART
PROVIDER WEB PART
CONSUMER WEB PART
CONSUMER WEB PART
Figure 17-24
From this diagram, you can see that it is possible to use a single provider Web Part with multiple
con-sumer Web Parts regardless of the Web Part Zone area in which the concon-sumer Web Part resides
When working with provider and consumer Web Parts, be aware that no matter how simple or
com-plicated the Web Part is, you must wrap the Web Part by making it a custom Web Part You do this
to expose the correct item or property from the provider Web Part or to utilize the passed value in the
correct manner for the consumer Web Part This chapter reviews a simple example of connecting Web
Parts Although many steps are required to accomplish this task, you definitely get a lot of value from
it as well
Building the Provider Web Part
In order to build a provider Web Part that can be utilized by any consumer Web Part residing on the
page, you first create an interface exposing the item you want to pass from one Web Part to another
For this example, suppose you want to provide a text box as a Web Part that allows the end user to
input a value This value is then utilized by a calendar control contained within a Web Part in an entirely different Web Part Zone on the page using the Calendar control’sCaptionproperty
This interface is demonstrated in Listing 17-15
Listing 17-15: Building an interface to expose the property used to pass to a Web Part
VB
Namespace Wrox.ConnectionManagement
Public Interface IStringForCalendar
Property CalendarString() As String End Interface
End Namespace
Continued
Trang 6namespace Wrox.ConnectionManagement
{
public interface IStringForCalendar
{
string CalendarString { get; set;}
}
}
From this bit of code, you can see that the interface,IStringForCalendar, is quite simple It exposes only
a single String property —CalendarString This interface is then utilized by the custom provider Web
Part shown next
The custom provider Web Part is built like any other custom Web Part in the manner demonstrated
earlier in this chapter The only difference is that you also provide some extra details so ASP.NET knows
what item you are exposing from the Web Part and how this value is retrieved This custom provider
Web Part is illustrated in Listing 17-16
Listing 17-16: Building a custom provider Web Part
VB
Imports Microsoft.VisualBasic
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Namespace Wrox.ConnectionManagement
Public Class TextBoxChanger
Inherits WebPart Implements IStringForCalendar Private myTextBox As TextBox Private _calendarString As String = String.Empty
<Personalizable()> _
Public Property CalendarString() As String Implements _ Wrox.ConnectionManagement.IStringForCalendar.CalendarString Get
Return _calendarString End Get
Set(ByVal value As String) _calendarString = value End Set
End Property
<ConnectionProvider("Provider for String From TextBox", _
"TextBoxStringProvider")> _
Public Function TextBoxStringProvider() As IStringForCalendar Return Me
End Function
Continued
Trang 7Protected Overrides Sub CreateChildControls()
Controls.Clear()
myTextBox = New TextBox()
Me.Controls.Add(myTextBox)
Dim myButton As Button = New Button()
myButton.Text = "Change Calendar Caption"
AddHandler myButton.Click, AddressOf Me.myButton_Click
Me.Controls.Add(myButton)
End Sub
Private Sub myButton_Click(ByVal sender As Object, ByVal e As EventArgs)
If myTextBox.Text <> String.Empty Then
CalendarString = myTextBox.Text myTextBox.Text = String.Empty End If
End Sub
End Class
End Namespace
C#
using System;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
namespace Wrox.ConnectionManagement
{
public class TextBoxChanger : WebPart, IStringForCalendar
{
private TextBox myTextBox;
private string _calendarString = String.Empty;
[Personalizable]
public string CalendarString
{
get { return _calendarString; }
set { _calendarString = value; }
}
[ConnectionProvider("Provider for String From TextBox",
"TextBoxStringProvider")]
public IStringForCalendar TextBoxStringProvider()
{
return this;
}
protected override void CreateChildControls()
{
Controls.Clear();
myTextBox = new TextBox();
Controls.Add(myTextBox);
Button myButton = new Button();
myButton.Text = "Change Calendar Caption";
myButton.Click += this.myButton_Click;
Continued
Trang 8} private void myButton_Click(object sender, EventArgs e) {
if (myTextBox.Text != String.Empty) {
CalendarString = myTextBox.Text;
myTextBox.Text = String.Empty;
} } }
}
Not only does this Web Part inherit theWebPartclass, this provider Web Part implements the interface,
IStringForCalendar, which was created earlier in Listing 17-15 FromIStringForCalendar, the single
Stringproperty is utilized and given thePersonalizable()attribute The important bit from the code
presented in Listing 17-16 is theTextBoxStringProvider()method This method returns a type of
IStringForCalendarand is defined even further using theConnectionProviderattribute This attribute
enables you to give a friendly name to the provider as well a programmatic name that can be used within
the consumer custom Web Part that will be built shortly
Using theCreateChildControls()method, you layout the design of the Web Part In this case, a text box
and button are the only controls that make up this Web Part In addition to simply laying out the controls
on the design surface, you use this method to assign any specific control events — such as a button-click
event by assigning handlers to the controls that require them
Finally, from within the button-click event of this Web Part (myButton_Click), the exposed property
ofIStringForCalendaris assigned a value Everything is now in place for a consumer Web Part The
construction of this second Web Part is demonstrated next
Building the Consumer Web Part
After you have a provider Web Part in place on your page, you can utilize the object it supplies for any
number of consumer Web Parts on the same page In this example, however, you are interested in using
theStringvalue coming from the TextBox control in the provider Web Part The consumer Web Part
takes thisStringand assigns it as the value of the Calendar control’sCaptionproperty The construction
of the consumer Web Part is illustrated in Listing 17-17
Listing 17-17: The consumer Web Part
VB
Imports Microsoft.VisualBasic
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Namespace Wrox.ConnectionManagement
Public Class ModifyableCalendar
Inherits WebPart
Continued
Trang 9Private _myProvider As IStringForCalendar
Private _stringTitle As String
Private myCalendar As Calendar = New Calendar()
<ConnectionConsumer("Calendar Title Consumer", "CalendarTitleConsumer")> _
Public Sub RetrieveTitle(ByVal Provider As IStringForCalendar)
_myProvider = Provider
End Sub
Protected Overrides Sub OnPreRender(ByVal e As EventArgs)
EnsureChildControls()
If Not (Me._myProvider Is Nothing) Then
_stringTitle = _myProvider.CalendarString.Trim() myCalendar.Caption = _stringTitle
End If
End Sub
Protected Overrides Sub CreateChildControls()
Controls.Clear()
Me.Controls.Add(myCalendar)
End Sub
End Class
End Namespace
C#
using System;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
namespace Wrox.ConnectionManagement
{
public class ModifyableCalendar : WebPart
{
private IStringForCalendar _myProvider;
string _stringTitle;
Calendar myCalendar;
[ConnectionConsumer("Calendar Title Consumer", "CalendarTitleConsumer")]
public void RetrieveTitle(IStringForCalendar Provider)
{
_myProvider = Provider;
}
protected override void OnPreRender(EventArgs e)
{
EnsureChildControls();
if (_myProvider != null)
{
_stringTitle = _myProvider.CalendarString.Trim();
myCalendar.Caption = _stringTitle;
}
Continued
Trang 10} protected override void CreateChildControls() {
Controls.Clear();
myCalendar = new Calendar();
Controls.Add(myCalendar);
} }
}
This new custom Web Part,ModifyableCalendar, is simply a class that inherits fromWebPartand
noth-ing more It requires a reference to the interfaceIStringForCalendar BecauseIStringForCalendaris
part of the same namespace, you can provide a simple reference to this interface
Your consumer Web Part requires a method that is the connection point for a provider Web Part on the
same page In this case, theRetrieveTitle()method is constructed using theConnectionConsumer
attribute before the method declaration Like theConnectionProviderattribute that was utilized in the
provider Web Part, theConnectionConsumerWeb Part enables you to give your Web Part a friendly
name and a reference name to use programmatically
Then, the value retrieved from the provider Web Part is grabbed from within thePreRender()method
of the Web Part and assigned to the Calendar control before the actual Calendar control is placed on the
page from within theCreateChildControls()method
Now that both a provider and a consumer Web Part are available to you, the next step is to get them both
on an ASP.NET page and build the mechanics to tie the two Web Parts together This is demonstrated
next
Connecting Web Parts on an ASP.NET Page
When in the process of connecting Web Parts, remember that you need a provider Web Part and a
con-sumer Web Part These items are detailed in Listings 17-16 and 17-17, respectively When working with
the process of connecting Web Parts, it is not simply a matter of placing both of these items on the page
to get the connections to take place In addition to this step, you have to wire the Web Parts together
This wiring of Web Part connections is done through the WebPartManager control that is discussed at
the beginning part of this chapter The ASP.NET page used for this example is detailed in Listing 17-18
Listing 17-18: The ASP.NET page that connects two Web Part controls
<%@ Page Language="VB" %>
<%@ Register Namespace="Wrox.ConnectionManagement"
TagPrefix="connectionControls" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Connecting Web Parts</title>
</head>
<body>
Continued