Testing the Application
To test the application, press F5 (Run) in Visual Studio. From the resulting page in the browser, select an author from the first DropDownList control to fill the second DropDownList control with that author's titles (see
Figure 3).
 | |
Figure 3. Dependent Lists in Action: Selecting an author from the first dropdown list shows titles written by that author's in the second dropdown list. |
How it Works
Obviously, this doesn't all happen magically, even though you didn't have to write any client-side code at all. The reason this works lies in the configuration discussed earlier in this article:
<cc1:CascadingDropDownProperties
Category="Author"
TargetControlID="DropDownList1"
ServiceMethod="GetAuthors"
ServicePath="WebService.asmx"
PromptText="Please select an author" />
<cc1:CascadingDropDownProperties
Category="Title"
TargetControlID="DropDownList2"
ParentControlID="DropDownList1"
ServiceMethod="GetTitles"
ServicePath="WebService.asmx"
PromptText="Please select a title" />
The preceding configuration code associates the two DropDownList controls with the backend Web servicescausing the framework to write client-side code that handles changes to the selected item in the DropDownList control, calling the specified Web service when the user changes the selection to a valid item. The framework then uses the Web service-provided data to automatically populate the list with the appropriate items.
Caching to Improve Performance
Because the application must connect to the database server to fetch the author list whenever a user first loads the application, it might be a good idea to cache the author list to limit the server workload imposed by subsequent launches by other users. Thus, you can improve the
GetAuthors() function by using the HttpContext.Current.Cache object:
<WebMethod()> _
Public Function GetAuthors( _
ByVal knownCategoryValues As String, _
ByVal category As String) As _
CascadingDropDownNameValue()
Dim values As New System.Collections.Generic.List( _
Of AtlasControlToolkit.CascadingDropDownNameValue)
Dim ds As DataSet
' ---check the cache---
ds = HttpContext.Current.Cache("authors")
If ds Is Nothing Then
' ---create new dataset---
Dim conn As New SqlConnection( _
"Data Source=.\SQLEXPRESS;Initial " & _
"Catalog=pubs;Integrated Security=True")
Dim comm As New SqlCommand("SELECT au_id, au_lname, " & _
"au_fname FROM authors", conn)
Dim ad As New SqlDataAdapter(comm)
ds = New DataSet
ad.Fill(ds)
'---save the dataset into cache---
HttpContext.Current.Cache.Insert("authors", ds)
Else
ds = CType(HttpContext.Current.Cache("authors"), DataSet)
End If
For Each row As DataRow In ds.Tables(0).Rows
values.Add(New CascadingDropDownNameValue( _
row("au_lname") & " " & row("au_fname"), row("au_id")))
Next
Return values.ToArray
End Function
Note that the new
GetAuthors() version uses a DataSet rather than a DataReader. The new version now checks whether the cache contains the "authors" dataset, and if not, creates and caches it. When another user loads the page, the function fetches the dataset from the cache instead of from the database. As usual, you can modify the above code to support expiration, etc., but I'll leave such enhancements as an exercise for readers.
One last thought regarding caching. While I have cached only the authors list, it might also be good to cache some of the titles list for those authors that are most likely to be chosen. With a large user base, this decision will save far more resources than simply caching the authors list.
In this article, you have seen how easy it is to use the CascadingDropDown control from the Atlas Control Toolkit to control the items list of DropDownList controls. Note that you don't have to write any client-side code; all you need to do is tie the CascadingDropDown control's
ServiceMethod to a back end Web service.