现在在公司的一个项目中使用到AtlasToolkit中的CacadingDropDown,有一些需要有多选框(即Asp.Net服务器控件中的ListBox,HTML代码中的<select multiple="true"></select>),但是CascadingDropDown并不支持多选,全部是单选. 经过一翻研究和尝试之后,终于给它增加了多选的功能,于是就有了这篇文章.
AtlasToolkit中的控件由几个部分组成
- Bihavior:这是一个客户端Js文件,定义了控件在客户端的行为,应该是AtlasTookit控件的核心部分
- Extender:这是控件的服务端支持,用于支持控件的服务端操作
- Properties:这是服务端配置类
- Designer:设计时支持
在开始之前,先看看效果(注意最下一行字,这就是多选的结果),
要改造CascadingDropDown,就要拿这几个部分分别开刀.现在一步一步来.
第一步,使它在服务端支持ListBox
虽然多选框跟单选下拉框在客户端都是Select,但在服务端却是两个不同的控件.CascadingDropDown本身只支持DropDownList
public class CascadingDropDown : ExtenderControlBase<CascadingDropDownProperties, DropDownList>
上面是Extender文件中CascadingDropDown的声明,它继承自ExtenderControlBase,注意红色部分,因为这里的声明使它仅仅支持DropDownList,现在我们要把它改成ListControl,这样就可以同时支持ListBox和DropDownList了,因为这两个都继承自ListControl.
除了这里,Properties和Designer中的相应的泛型声明都要改成ListControl.
以上做的是在接口上支持ListBox,现在要使它在行为上支持ListBox.这个只需要改Extender一个文件就可以了.
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
foreach (CascadingDropDownProperties cascadingDropDownProperties in TargetProperties)
{
ListControl ctrl = (ListControl)FindControlHelper(cascadingDropDownProperties.TargetControlID);
if (ctrl is DropDownList)
{
DropDownList dropDownList = ctrl as DropDownList;
dropDownList.Items.Clear();
dropDownList.Items.Add(cascadingDropDownProperties.ClientState);
}
else if (ctrl is ListBox)
{
ListBox listBox = ctrl as ListBox;
listBox.Items.Clear();
if (cascadingDropDownProperties.ClientState == null)
return;
foreach (string item in cascadingDropDownProperties.ClientState.Split(','))
{
listBox.Items.Add(item);
}
}
}
}protected override void OnPreRender(EventArgs e)
{
foreach (CascadingDropDownProperties cascadingDropDownProperties in TargetProperties)
{
ListControl ctrl = (ListControl)FindControlHelper(cascadingDropDownProperties.TargetControlID);
if (ctrl is DropDownList)
{
DropDownList dropDownList = ctrl as DropDownList;
dropDownList.Items.Clear();
}
else if (ctrl is ListBox)
{
ListBox listBox = ctrl as ListBox;
listBox.Items.Clear();
}
}base.OnPreRender(e);
}
好了,上面就是改变服务端的,使之确实地支持ListBox,到这里服务端就修改完成了.
第二步,修改Behavior,以下的修改后的Behavior文件中的set_SelectedValue, 只需要修改这个地方就可以了.
this.set_SelectedValue = function(value) {
if( this.control != null && this.control.element != null && this.control.element.multiple )
{
var e = this.control.element;
//是多选框,即ListBox
_selectedValue = new Array();
for( var i = 0; i < e.options.length; ++i )
{
if( e.options[i].selected )
_selectedValue[ _selectedValue.length ] = e.options[i].value;
}
AtlasControlToolkit.CascadingDropDownBehavior.callBaseMethod(this, 'set_ClientState', [ _selectedValue.toString() ]);
}
else
{
_selectedValue = value;
AtlasControlToolkit.CascadingDropDownBehavior.callBaseMethod(this, 'set_ClientState', [ _selectedValue ]);
}
}
好了,编译,控件的发行就完成了.接下来说使用.
第一步:把ASPX文件中的DropDownList改成ListBox,并且加上SelectMode="Multiple"
第二步:使用类似以下的代码来取值
foreach (ListItem item in DropDownList3.Items)
{
//if (item.Selected)
color += RemoveValueText(item.Value) + ","
}
注意,我把红字部分,这一行是不需要的,因为传回来的所有Item都是被选中的,没有被选中的项并没有被传回来.