一个简单的级联DropdownList自定义控件

本文介绍了一个简单的级联DropdownList自定义控件,该控件避免了选择时页面刷新或ajax延迟,提供了良好的用户体验。通过使用数据库脚本创建数据,然后在ASP.NET中进行数据绑定。控件通过DataTable数组分别存储tbl1和tbl2表的数据,并在客户端通过脚本控制显示。控件的状态保持是实现中的难点,同时具备快速显示和样式控制的优点,但依赖ViewState并需要改进。

效果:

避免了选择item时页面刷新或ajax延迟。

测试用的数据库脚本和数据:

create table tbl1
(
    CityID 
int primary key identity(1,1),
    CityName 
nvarchar(50not null,
)
go
create table tbl2
(
    AreaID 
int primary key identity(1,1),
    AreaName 
nvarchar(50not null,
    AreaCity 
int references tbl1(CityID)
)
go
create table tbl3
(
    BuildingID    
int primary key identity(1,1),
    BuildingName 
nvarchar(50not null,
    BuildingArea 
int references tbl2(AreaID)
)
go

insert into tbl1 values('淄博')
insert into tbl1 values('青岛')

insert into tbl2 values('张店',1)
insert into tbl2 values('辛店',1)
insert into tbl2 values('四方',2)
insert into tbl2 values('市南',2)

insert into tbl3 values('Building1',1)
insert into tbl3 values('Building2',1)
insert into tbl3 values('Building3',1)
insert into tbl3 values('Building4',2)
insert into tbl3 values('Building5',3)
insert into tbl3 values('Building6',3)
insert into tbl3 values('Building7',4)
insert into tbl3 values('Building8',4)

注意表间关系。

使用:

导入前缀
<%@ Register TagPrefix="cc1" Namespace="sss" Assembly="构架测试" %>
定义控件
<cc1:CascadeDropdownLists ID="myDropdown" Direction="Vertical" runat="server"  DropDownListStyle-BackColor="AliceBlue" DropDownListStyle-Width="160px"/>
数据绑定
  DataTable[] dts = new DataTable[] { new DataTable(), new DataTable() };
                SqlDataAdapter da = new SqlDataAdapter("select * from tbl1", constr);
                da.Fill(dts[0]);
                da.SelectCommand.CommandText = "select * from tbl2";
                da.Fill(dts[1]);

                myDropdown.DataSource = dts;
                myDropdown.DataBind();

原理就是每个datatable对应一个下拉列表,其中的记录对应下拉列表的选项。
通过客户端脚本根据各下拉列表间的关系控制那些选项显示,哪些不显示。
难点在于控件状态的保持。
实现了简单的样式控制。
优点在于速度快,显示效果好。
缺点是必须要用viewstate,否则无法取回提交数据。需要改进。 

 

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.ComponentModel;
using System.Collections.Generic;
using System.Collections.Specialized;

namespace sss
{
    [ToolboxData(
"<{0}:CascadeDropdownLists runat="server"></{0}:CascadeDropdownLists>")]
    
public class CascadeDropdownLists : WebControl//, INamingContainer,IPostBackEventHandler, IPostBackDataHandler
    {
        
Properties

        
索引器

        
Methods

        
Fields
        
        
static CascadeDropdownLists()
        
{
            refreshNext_ref 
= string.Concat("zhyFunc_"typeof(CascadeDropdownLists).FullName.Replace('.''I'), "_refreshNext");
            initCDDL_ref 
= string.Concat("zhyFunc_"typeof(CascadeDropdownLists).FullName.Replace('.''I'), "_initCDDL");
            refreshNextForPostBack_ref 
= string.Concat("zhyFunc_"typeof(CascadeDropdownLists).FullName.Replace('.''I'), "_refreshNextForPostBack");

            refreshNext 
= string.Concat("function ", refreshNext_ref, @"(list)
            {
                var nextList;
                try
                {
                    var index = list.id.lastIndexOf('_');
                    var front = list.id.substring(0,index+1);
                    var count = list.id.substring(index+1);
                    var count2 = parseInt(count)+1;
                    nextList = document.getElementById(front + count2);
                    if(!nextList)
                    {
                        return;
                    }
                }
                catch(e)
                {   //没有下一级
                    return;
                }

                while(nextList.options.length!=0)
                {   //移除下级下拉列表的所有item
                    nextList.options.remove(0);
                }

                for(var i=0;i<nextList.bakOptions.length;i++)
                {
                    if(nextList.bakOptions[i].ParentPtr == list.options[list.selectedIndex].value)
                    {
                        nextList.options.add(nextList.bakOptions[i]);
                    }
                }
                nextList.selectedIndex=0;
" + refreshNext_ref + @"(nextList);
            }
");
            refreshNextForPostBack 
= string.Concat("function ", refreshNextForPostBack_ref, @"(list)
            {
                var nextList;
                try
                {
                    var index = list.id.lastIndexOf('_');
                    var front = list.id.substring(0,index+1);
                    var count = list.id.substring(index+1);
                    var count2 = parseInt(count)+1;
                    nextList = document.getElementById(front + count2);
                    if(!nextList)
                    {
                        return;
                    }
                }
                catch(e)
                {   //没有下一级
                    return;
                }

                for(var i=0;i<nextList.options.length;)
                {
                    if(nextList.options[i].ParentPtr != list.options[list.selectedIndex].value)
                    {
                        nextList.options.remove(i);
                    }
                    else
                    {
                        i++;
                    }
                }
" + refreshNextForPostBack_ref + @"(nextList);
            }
");

            initCDDL 
= string.Concat("function ", initCDDL_ref, @"(list)
            {
                list.bakOptions = new Array();
                for(var i=0; i<list.options.length;i++)
                {   //保存所有item
                    list.bakOptions.push(list.options.item(i));
                }
            }
");
        }

    }


}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值