剖析CascadingDropDown控件的工作原理
来源:互联网 发布:二维彩超图数据看男女 编辑:程序博客网 时间:2024/04/29 00:33
这篇文章主要介绍了CascadingDropDown控件的工作原理,以便我们能够添加更多的自定义功能。
Introduction
CascadingDropDownExtender
is one of the most popular AjaxControlToolkit extenders. But, because there is a help article about the server-side part of the control and almost nothing about the client-side (that really makes it work), developers became baffled when they needed to add some advanced event handling or customization.
I think that if you understand how it works, it is much easier to implement your own functionality. So, in this article, I'll describe how the CascadingDropDown
works, and then I'll try to answer some common questions.
Little server
To render it shortly for those who do not know - CascadingDropDown
– is an extender control used to fill the data in one DropDownList
depending on the value chosen in another DropDownList
. It gets all the necessary data through AJAX using a web method. Now, let’s consider its organization in more details.
So, the CascadingDropDown
is an extender for DropDownList
. As the target control, we set the "dependent" (or child) DropDownList
(i.e., the one that is going to be filled). To set the ID of the parent control, we use the ParentControlID
property, which, by the way, is not required (i.e., there can be no parent DropDownList
). Other required properties (in addition to TargetControlID
) are Category
and ServiceMethod
. The ServiceMethod
contains the name of the web method used by CascadingDropDown
, and Category
fulfills the role of filter name and will be passed to the web method as part of one of the parameters. The optional properties are:
PromptText
(text to display before the user has selected a value from theDropDownList
),PromptValue
(value set whenPromptText
is displayed),EmptyText
(text to display when theDropDownList
has no data to display),EmptyValue
(value set whenEmptyText
is displayed),LoadingText
(text which is displayed during the loading),ServicePath
(the path to web-service; if you do not declare it, thePageMethod
will be used instead),ContextKey
(place for storing any additional information),UseContextKey
(tells you to pass or not to passContextKey
as one of the properties to the web-method),SelectedValue
(default value for the childDropDownList
).
Apart from the above described properties, the CascadingDropDown
has a couple of helper static methods which can be used in web methods, but they will be discussed later. All that the CascadingDropDown
does on the server-side is collect the values of the above-described properties into the script descriptor and «sends» it to the related client class that is derived from Sys.UI.Behavior
(exactly – from AjaxControlToolkit.BehaviorBase
). Then, all the main process runs on the client-side:
Big client
In the initialize
method, override the handlers subscribed on the change
event of the child and parent (if defined) select
DOM elements. Also, if the parent select
is specified, there appears a kind of bond between the parent and child select
s: the child select
receives the CascadingDropDownParentControlID
field that refers to the parent select
, and the parent select
gets (if it already does not have it) an array field called childDropDown
, to which a reference to the child select
is added. Besides all these, during the initialization stage, all options are removed from the child select
DOM element, the CascadingDropDownCategory
field (which will contain the value of the Category
property) is added to it, the text from PromptText
or LoadingText
properties is put in the parent select
, and some other minor actions are performed. Also, if the child select
has no parent, or the parent is specified and in the moment initialize is called, its selected value isn’t equal to PromptValue
or EmptyValue
, the child select
will be filled by data (i.e., there will be the same action as when the user changes the value of the parent select
). So, it’s high time to look how the data filling occurs.
Everything begins in the _onParentChange
method (notice the underline prefix - this method isn't for public usage). As it was already said, the web method passes 2 or 3 parameters depending on the UseContextKey
value. These arguments are knownCategoryValues
, category
, and contextKey
. All these arguments are strings. It is logical that _category
and _contextKey
field values are passed as second and third parameters. The value for the first one is more interesting. It is formatted as follows: if the child select
has no parent, the value is null
. If the parent select
is specified, then its CascadingDropDownCategory
field value and selected value are added to knownCategoryValues
. If the parent select
has the CascadingDropDownParentControlID
field specified, then the parent of the parent select
is taken and the above described actions are repeated, and this continues to the end of the hierarchy. New pairs are added to the beginning of knownCategoryValues
, and, as a result, knownCategoryValues
will look like this:
Here, I would like to take your attention to some unobvious fact. To make this all work, the parent select
must have the CascadingDropDownCategory
field specified. If there is a CascadingDropDownBehavior
client control that has the parent select
as the target control, this field will be specified automatically. Otherwise, you will have to define the field yourself.
But let’s return to the web method. It is called not through the generated proxy, but directly – through the Sys.Net.WebServiceProxy.invoke
method. After collecting all the parameters for the web method, the populating
(Object
, Sys.CancelEventArgs
) client-side event is raised, and if the Sys.CancelEventArgs.cancel
property wasn’t set to false
in the handlers, the request is sent to the server. The web method should return the array of CascadingDropDownNameValue
objects.
If the web method call fails, then the information about the error (for some unknown for me reason) will be put in the child select
as options. If the web method call returns successfully, then the child select
options collection will be filled with the received values, and if among one of the received objects, the CascadingDropDownNameValue.value
field equals to SelectedValue
, or CascadingDropDownNameValue.isDefaultValue == true
, its value will be selected. Regardless whether there were or were no mistakes, in the end, the populated
(Object
, Sys.EventArgs
) client-side event is raised. That’s all, the update is finished.
It’s worth mentioning, that at any change of the selected value in the child select
, the SelectionChanged(Object, AjaxControltoolkit.CascadingDropDownSelectionChangedEventArgs)
client-side event is raised:
At the moment of writing the article, there was a bug. The LoadingText
is set before the populating
event is raised, and if the request was cancelled, LoadingText
remains in the child select
instead of promptText
or old options, and this can make the user puzzled.
And when we know more...
Now, when we have more or less got into the principle of work, we can make some conclusions:
- As
CascadingDropDown
works via a web method (web service method orPageMethod
), it has nothing to do with the server-side or client-side page life-cycles. And, consequently, when theselect
DOM element is updated withCascadingDropDown
, there will be no postbacks, no ASP.NET validators will act, no events of life-cycle will be raised, noSelectedIndexChanged
will work etc. Besides, for the work ofCascadingDropDown
, you do not need to put it inUpdatePanel
– it won’t use it all the same. - As
CascadingDropDown
works via a web method, the order of parameters is unimportant. What is important is that the signature of the web method matches the types and the names of the parameters. I.e., the names of the arguments must be the same as given in the documentation. And again, it is indifferent what you use – web service method orPageMethod
. CascadingDropDown
has no server logic (web method is not counted because it is not part of a control). All that the server-side part of the control performs is help us to simplify the creation of the client-side part. That is whyCascadingDropDownBehavior
can be created and used separately from server-side and, more than that, without ASP.NET 2.0 at all. Just add the required scripts to the page and use the $create method:
The only thing that we haven’t considered here is the ClientStateFieldID
property. We need to pass the ID of some hidden-column to this property, so CascadingDropDownBehavior
can use this hidden field to store the selected value during postbacks (it is called “ClientState”).
- Unlike
UpdatePanel
, requests sent throughSys.Net.WebServiceProxy.invoke
are performed independently from each other. That is why we can have concurrency problems on the client if request executions can take a long time. For example: the user has selected some value in the parentselect
. This action will send the first request. Without waiting for the answer, the user chooses some other value in the same parentselect
. And here we get the second request. Let’s suppose that to perform the second request, significantly less time is needed than for performing the first one. And as a result, the answer to the second request is given first. The childselect
has been filled, the user has made up his mind to choose something in it, and at this moment, the answer to the first request is given, and theselect
is filled with non-valid-at-that-moment values. As a result, the values in the childselect
do not correspond to the choice in the parentselect
. I do not know whether or not we can consider this as a bug. However, we will have to resolve this situation on our own. - In order to perform client-side validation, control the priority of requests, and to show and hide an animated GIF instead of a “Loading” message, we need to use the
populating
andpopulated
client-side events. Again, to make it clear: we must subscribe to the events of theCascadingDropDownBehavior
that has the childselect
as its target element, but these events will be raised when the user changes selection in the parentselect
. - Because it is required to have the
CascadingDropDownCategory
property specified, it is more preferable (though not required) to fill the topDropDownList
withCascadingDropDown
instead of classic databinding - The location of
CascadingDropDown
in the web form (and, consequently, the order of their initialization) plays an important role.CascadingDropDown
, filling the parentselect
, should be initialized (and placed) first.
And in the end, about those two helper methods I’ve mentioned in the beginning:
- The
ParseKnownCategoryValuesString
method parses theknownCategoryValues
web method argument fromString
toStringDictionary
. That is rather useful. - The
QuerySimpleCascadingDropDownDocument
method can help you to retrieve a collection ofCascadingDropDownNameValue
objects from a dataset, based on an existing category/valueStringDictionary
. I really don’t like datasets, so I don’t use this method. But if you like them, you can see this tutorial.
- 剖析CascadingDropDown控件的工作原理
- cascadingDropdown 控件的使用
- CascadingDropDown控件
- CascadingDropDown控件
- 剖析锂电池的工作原理
- 剖析锂电池的工作原理
- 省市级联(CascadingDropDown控件的应用)
- 省市级联(CascadingDropDown控件的应用)
- GDB的基本工作原理剖析
- GDB的基本工作原理剖析
- 深入剖析jsp的工作原理
- AJAX控件之CascadingDropDown
- ajax控件 CascadingDropDown用法
- altas(ajax)控件(六):CascadingDropDown 联动选择的下拉框
- altas(ajax)控件(六):CascadingDropDown 联动选择的下拉框
- 使用CascadingDropDown控件连接数据库
- ARM MMU工作原理剖析
- ARM MMU工作原理剖析
- 反射,java的灵魂
- mysql 找回密码
- 一道划痕
- 兰*蝶
- linux下搭建gloox开发平台
- 剖析CascadingDropDown控件的工作原理
- ava下Class.forName的作用是什么,为什么要使用它
- 团结自强庆回归 4万港人大巡游
- TAO提供的initial reference
- C#读取Win32标准DLL文件中的字符串资源
- Visual Assist X 官方网站
- 新的路途
- 新人
- has a / is a 的区别