65.9K
CodeProject 正在变化。 阅读更多。
Home

多选下拉列表控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.24/5 (17投票s)

2008年3月8日

CPOL

7分钟阅读

viewsIcon

343170

downloadIcon

17297

这个简单轻量级的控件允许用户从一个包含复选框项目的下拉列表中选择多个项目。

MSDD_Control.jpg

引言

这是一个信息时代,一切都在走向互联网。如今,用户似乎比以往任何时候都更倾向于在线购物。日复一日,由于激烈的竞争,公司越来越难以让在线用户满意。在互联网上,所有网站在吸引更多点击和使在线商店成功方面的一个共同点是使用最先进的网络工具和控件,以及它们在网页上的呈现方式以及其他信息。

Visual Studio .NET 提供了广泛的 Web 服务器控件。这些控件具有 DHTML 特性(例如 AutopostbackEnableSessionState),同时易于使用。它们在网页上呈现大量信息也需要较小的空间。其中两个控件是 DropdownListCheckboxList。这两个控件功能强大且功能丰富,因为它们提供了添加和删除单个项目的有效方法,支持多选功能,并且还具有 DataSource 属性,这使它们符合数据绑定控件的资格。这两个控件的一个共同限制是它们在页面上显示信息的方式。与其他控件相比,它们渲染信息需要相对更多的空间。但是,现在我们已经到了公司之间达成合作并试图涉足多个业务的阶段。他们希望在其网站上看到尽可能多的内容。他们无法承担占用大量空间仅用于显示一种信息的控件。

当我遇到同样的情况,需要创建一个包含 15 到 20 个搜索过滤器并且每个过滤器都有超过 25 个项目的搜索页面时,我决定不将整个页面都用列表框或复选框列表占据,而是开发一个用户控件,该控件不仅能显示完整的复选框项目列表,还能作为一个下拉列表。

关于用户控件

这是一个易于使用且轻量级的控件。代码也相对容易理解。我使用 .NET 和 C# 作为服务器端,使用 JavaScript 作为客户端脚本进行了开发。虽然它不是一个功能齐全的 Web 服务器控件,但它提供了一些有用的功能,可以帮助用户轻松地显示和管理页面上的信息。以下是这些功能的一小部分列表:

  • 自动回发
  • 通过此属性,当触发 OnSelectedItem 事件时,页面将自动回发到服务器,这仅在设置此属性值为 true 且切换按钮被按下时发生。

  • 启用视图状态
  • 一个属性,用于指定是否必须将控件的当前值保存在 __VIEWSTATE 隐藏字段中,并在页面回发时恢复。对于本控件,为了显示选定选项的列表,我使用了 ASP.NET TextBox 控件,它将负责处理我们控件的视图状态。

  • DataSource
  • 通过此属性,控件可以获取或设置 DataTable 类型的数据源。这使该控件成为一个真正的数据绑定控件。除此之外,该控件还支持 DataTextFieldDataValueField,类似于标准下拉列表控件,分别用于列表项目的文本内容和每个列表项目的

  • Z-Index
  • 此属性设置我们用户控件的堆叠顺序。当同一页面上使用多个控件实例时,它非常有用。由于控件向下方扩展,堆叠顺序更高的实例始终位于堆叠顺序较低的实例的前面。

    MSDD_Overlap.jpg

  • 展开/折叠

  • 就像普通的下拉列表控件一样,此用户控件可以通过单击页面上的任意位置或控件本身(但排除显示选择列表的区域)自动折叠。这是因为用户可能想要选择多个项目。

  • 选定选项

  • 回发时,控件将以逗号分隔的列表形式将其当前状态传递给服务器,可用于进一步处理。

Using the Code

在您的 ASP.NET 项目中使用此控件相当简单,因为它通过其公开的属性获取或设置所有内容。在页面上,首先需要注册它,可以通过将以下行粘贴到 ASPX 页面的顶部来完成:

<%@ Register TagPrefix="DDMS" 
    TagName="MultiSelectDropDown" Src="MultiSelectDropDown.ascx" %>

注册完成后,可以通过将以下代码粘贴到页面上但位于 HTML body 内部的任何位置来初始化控件。请注意,在附带的演示项目中,我将控件封装在 <DIV> 标签中,这当然不是必需的,但如前所述,为了避免 z-index 问题,最好将其包含在 <DIV> 中并根据其在页面上的出现顺序为其设置 z-index 值。

<div id="divMultiSelectDropDown1" 
     style="Z-INDEX: 101; LEFT: 20px; POSITION: absolute; TOP: 20px">
   <ddms:multiselectdropdown id="MultiSelectDropDown1" runat="server">
   </ddms:multiselectdropdown><br>
   <br>
</div>

<div id="divMultiSelectDropDown2" 
     style="Z-INDEX: 100; LEFT: 20px; POSITION: absolute; TOP: 60px">
   <ddms:multiselectdropdown id="Multiselectdropdown2" runat="server">
   </ddms:multiselectdropdown>
</div>

ASPX 端就这些了。现在该编写一些服务器端代码了。要加载和配置控件,可以将以下代码行粘贴到 Page_OnLoad 事件中。下面的代码使用了两个单独的控件实例,MultiSelectDropDown1MultiSelectDropDown2CallingPage 是控件公开的一个属性,它将向控件提供宿主页面的引用。通过使用此引用,用户控件将发出 __doPostBack 方法所需的代码。

protected void Page_Load(object sender, System.EventArgs e)
{
    if(!this.IsPostBack)
    {
        this.MultiSelectDropDown1.DataSource = GetCurrencyDataSource();
        this.MultiSelectDropDown1.DataTextField = "Description";            
        this.MultiSelectDropDown1.DataValueField = "CurrencyID";

        this.MultiSelectDropDown1.AutoPostBack = true;
        this.MultiSelectDropDown1.DataBind();                            

        this.Multiselectdropdown2.DataSource = GetEmployeeDataSource();
        this.Multiselectdropdown2.DataTextField = "EmpName";
        this.Multiselectdropdown2.DataValueField = "EmpID";
                
        this.Multiselectdropdown2.AutoPostBack = false;
        this.Multiselectdropdown2.DataBind();    
    }
    
    this.MultiSelectDropDown1.CallingPage = this;
    this.Multiselectdropdown2.CallingPage = this;

    this.MultiSelectDropDown1.OnItemsSelected += 
      new MultiSelectDropDownDelegate(MultiSelectDropDown1_OnItemsSelected);
}

最后一件事是注册 OnSelectedItem 事件并提供其事件处理程序。对于事件参数,我创建了一个名为 MultiSelectDropDownItemSelectedEventArgs 的单独类。该类将包装参数 (__EVENTARGUEMNT) 并将它们传递给事件处理程序。演示项目将为您提供如下所示的输出:

private void MultiSelectDropDown1_OnItemsSelected(object sender, 
             MultiSelectDropDownItemSelectedEventArgs args)
{
    this.tbSelectedFullText.Text = string.Empty;
    this.tbSelectedOptionsValue.Text = string.Empty;
    this.lbSelectedItemList.Items.Clear();

    this.tbSelectedOptionsValue.Text = args.SelectedOptionValueText;
    this.tbSelectedFullText.Text = args.SelectedOptionText;
    foreach(string selectedOption in args.SelectedOptionList)
        this.lbSelectedItemList.Items.Add(selectedOption);
}

MSDD_ResultView.jpg

范围

在我开始着手开发该控件之前,和大多数其他开发人员一样,我也试图在互联网上寻找一个具有类似外观和功能的控件来支持代码重用(您懂的;)。在未能找到之后,我决定自己承担这项工作,也为那些可能对在他们的项目中使用它感兴趣的人。

就控件的范围而言,它可以扩展到 .NET 的两个版本(1.1 和 2.0)。请注意,不仅网页,其他用户控件也可以托管此用户控件。

关注点

我想对我在编写此控件时学到的一些东西以及遇到的一些小问题发表评论。

  • CheckBoxList 和 <ASP:CheckBox> 不是正确的选择

  • 我花了些时间来决定使用哪个控件来显示复选框列表,因为 CheckBoxList 无法为单个项目设置属性。即使是服务器端的 <ASP:Checkbox> 也不是一个可行的选择,因为它不像 HTML 复选框那样具有 Value 属性。

  • UserControl 的 CLIENTID

  • 请记住,在开发一个将作为其他子控件容器的用户控件,并且在一个页面上拥有多个实例时,始终通过将其 ID 与父控件的 ID 连接来访问子控件。

  • __doPostBack、EVENTARGUMENT 和 EVENTTARGET
  • 我不得不编写自己的 __doPostBack 版本,因为只有当页面上至少有一个 .NET 内置服务器控件时,才能使用默认的 __doPostBack 版本。由于我们的用户控件本身将充当服务器端控件,因此我无法依赖其他 .NET 服务器控件生成的 __doPostBack,因为它们可能存在也可能不存在于页面上。

以下是我希望在控件中看到的一些功能。如果有人能通过实现以下功能来升级该控件,我将不胜感激;否则,我将在时间允许的时候(这意味着永远!!)自己来完成。

  • Items 集合的 Add 方法,即 Items.Add()
  • OnMouseOver 的橙色更改为 Windows 默认的“蓝色”。
  • 通过属性更改控件大小的功能。
  • 通过 AJAX 回发。

更新 1.1

  1. 已添加 Firefox 支持。
  2. VB.NET 版本已添加到附带的演示项目中(仅主文件,名为“MultiSelectDropDown.ascx.vb”)。
  3. 所有与样式相关的代码现已与 HTML 分离。已添加新的 CSS 文件以提高性能和速度。
© . All rights reserved.