The CascadingDropDown extender can be attached to a DropDownList control to automatically populate it based on the current selection of one or more parent DropDownList controls. The CascadingDropDown extender is designed to fit in a relatively common scenario in which the contents of one drop-down list depend on the selection of another list. With this arrange- ment, you don’t need to transfer to the client the entire data set from which a child list can select a subset of items to display in accordance with the selection on its parent. For example, suppose you want the user to select a country and a city in that country. To minimize data transfer and provide a friendlier user interface, you might want to keep the city list empty until a selection is made on the country list. When a country is selected, you get back to the server to download the list of cities available for that country. The CascadingDropDown extender sim- plifies this scenario by injecting some glue code into the client page and also making some assumptions on the structure of your page code.
All the logic about the contents of the set of DropDownList controls is expected to reside on a Web service. The Web service, in turn, can use any suitable method for storing and looking up any relevant data. The Web service, though, is somewhat forced to use a contracted schema. In particular, it needs to have a method with the following signature:
[WebMethod]
public CascadingDropDownNameValue[] GetDropDownContents( string knownCategoryValues, string category)
{ ... }
The name of the method can vary, of course. The CascadingDropDownNameValue type is an internal collection type that is designed to contain the name/value items to show in the drop- down list. Each drop-down list bound to the extender belongs to a category:
<act:CascadingDropDown ID="CascadingDropDown1" runat="server" TargetControlID="DropDownList1"
Category="Country"
PromptText="Please select a country"
ServiceMethod="GetDropDownContentsPageMethod" />
<act:CascadingDropDown ID="CascadingDropDown2" runat="server" TargetControlID="DropDownList2"
Category="City"
PromptText="Please select a city" LoadingText="Please, wait ..." ServicePath="CityFinderService.asmx"
ServiceMethod="GetDropDownContents" ParentControlID="DropDownList1" />
The content of the Category property is any name that helps the Web service method to under- stand what kind of data should be retrieved and the meaning of the input arguments. The PromptText property sets any text that you want to display in the drop-down list when no selection is currently made and the control is typically disabled. The LoadingText property indicates any text that has to be displayed while the drop-down list is being populated. The ServiceMethod property indicates the method to call to fill in the list control. If no ServicePath is specified, the method is assumed to be a page method. Finally, ParentControlID creates a hierarchy and designates a list to be the child of another list.
Each time the selection changes in a parent DropDownList control, the extender makes a call to the Web service and retrieves the list of values for the next DropDownList in the hierarchy. If no selection is currently made, the extender automatically disables the control. (See Figure 5-16.)
Figure 5-16 The CascadingDropDown extender in action on two drop-down lists
The DropShadow Extender
The DropShadow extender is designed to add a drop shadow to panel controls to make them look more professional. You can also set the opacity and width of the shadow:
<asp:Panel runat="server" ID="Panel1"> <div style="padding:8px">
<asp:TextBox ID="TextBox1" runat="server" /> </div>
</asp:Panel>
<act:DropShadowExtender ID="DropShadowExtender1" runat="server" TargetControlID="Panel1" Opacity=".65" Width="5" Rounded="true" />
The TargetControlID property sets the control that will be rendered with a drop shadow. This con- trol should generally be a Panel; however, as long as you don’t set rounded corners, it can also be any other ASP.NET control, such as a TextBox. You control the opacity of the shadow through the Opacity property. Values for the property range from 0.0 to 1.0, where 0 (or 0.0) means total trans- parency. Hence, the closer the value is to 1 (or 1.0) the darker the shadow will be.
The Rounded Boolean property indicates whether the surrounding panel and the shadow should have rounded corners. The default is false. Figure 5-17 shows the extender in action.
Figure 5-17 The DropShadow extender in action
The DynamicPopulate Extender
The DynamicPopulate extender is a sort of binder component that replaces the markup of a given control with the markup returned by a Web service method call. The extender can be seen as a shrink-wrapped and simplified version of the UpdatePanel control that we discussed in Chapter 4. It captures a client event and fires a remote call. The returned string is inserted in the page DOM as the child of the target element. Here’s an example:
<input type="button" id="Button1" runat="server" value="Refresh ..." /> <hr />
<b>Last updated: </b>
<asp:Panel runat="server" ID="Msg" Style="padding:2px;height:2em;" /> <act:DynamicPopulateExtender ID="DynamicPopulateExtender1" runat="server"
TargetControlID="Msg"
ClearContentsDuringUpdate="true" PopulateTriggerControlID="Button1" ServiceMethod="GetTimeOnServer" UpdatingCssClass="updating" />
When the user clicks on the specified item—in this case, the button named Button1—the extender starts working. It invokes the method GetTimeOnServer and replaces the subtree rooted in the Msg control with its output. The method GetTimeOnServer is a Web service method. You specify the URL to the service using the ServicePath property. If this property is not set, the method is assumed to be a page method defined either in the code file of the page or inline through a server <script> tag:
[WebMethod]
public string GetTimeOnServer(string contextKey) {
// Get the output—it can be HTML markup return DateTime.UtcNow.ToString(); }
ClearContentsDuringUpdate is a Boolean property that clears the contents of the target control during the update. If you want to display a special style or a bitmap during the operation, you set a CSS style through the UpdatingCssClass property. When creating such a CSS class, bear in mind that you should ensure the target control has a minimum height. (It must be explicitly set on panels.) You use the background-image CSS attribute to set the image to display. Note that you can use any HTML element to trigger the dynamic population of the target con- trol. It doesn’t have to be a button control; and it doesn’t have to be a submit button such as LinkButton or Button. In this case, in fact, the page will post back and you’ll lose the benefit of the ASP.NET AJAX platform.
Note You can also use a piece of JavaScript code to dynamically populate a given DOM element. In this case, you set the CustomScript property to the name of a JavaScript global function. Whether you use a custom script or a server method, you can use the ContextKey property of the extender to pass an arbitrary string to the code.