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

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果:

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

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

create   table  tbl1
(
    CityID 
int   primary   key   identity ( 1 , 1 ),
    CityName 
nvarchar ( 50 not   null ,
)
go
create   table  tbl2
(
    AreaID 
int   primary   key   identity ( 1 , 1 ),
    AreaName 
nvarchar ( 50 not   null ,
    AreaCity 
int   references  tbl1(CityID)
)
go
create   table  tbl3
(
    BuildingID    
int   primary   key   identity ( 1 , 1 ),
    BuildingName 
nvarchar ( 50 not   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、付费专栏及课程。

余额充值