现在在公司的一个项目中使用到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都是被选中的,没有被选中的项并没有被传回来.

posted on 2006-08-26 11:28  Lupin  阅读(1809)  评论(6编辑  收藏  举报