[分享]新封装的一个实现无刷新连动下拉列表类

近期由于项目需要实现大量的无刷新的连动下拉列表,感觉每个页面都copy一份javascript脚本的方法有点蠢,就产生了封一个通用类的念头,先是我同事myw研究了一个版本(这里特别感谢),感觉他的那个使用的限制太多,就在他的基础上改造了一下,产生了下面的版本,虽然还有一定的使用限制,但总的来说还是比较好用的,具体说说实现及使用方法吧!

1.实现方法:
其实原理很简单,先通过cs脚本初始化javascript脚本,再把javascript脚本通HttpContext.Current.Response.Write写入客户端,当然首先还需对一对DropDownList控件进行简单处理,限定是DropDownList的数据源datasource必须使用datatable,不过可以通过根据需要改造来适应其他类型的数据源;

直接看代码吧,还是比较简单的

using System;
using System.Data;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace NoRefreshJointDDL
{
    
/// <summary>
    
/// 实现两个无刷新联动的DropDownList
    
/// </summary>

    public class CNoFlashDownList:System.Web.UI.Page
    
{
        
#region 成员变量

        
//注册控件
        private System.Web.UI.WebControls.DropDownList ddlDriver;    //驱动方下拉列表
        private System.Web.UI.WebControls.DropDownList ddlDrivener;    //从动方下拉列表
        
        
//数据源
        private DataTable dtDriver;        //主动方数据源
        private DataTable dtDrivener;    //从动方数据源

        
//驱动部分
        private string strDriverValueField            = "";    //编码列
        private string strDriverTextField            = "";    //显示列
        private string strDriverRelation            = "";    //关系列

        
//从动部分
        private string strDrivenerValueField        = "";    //编码列
        private string strDrivenerTextField            = "";    //显示列
        private string strDrivenerRelation            = "";    //关系列

        
#endregion


        
#region 成员属性
        
/// <summary>
        
/// 驱动方关系列
        
/// </summary>

        public string DriverRelation
        
{
            
set{strDriverRelation = value;}
        }

        
        
/// <summary>
        
/// 从动方关系列
        
/// </summary>

        public string DrivenerRelation
        
{
            
set{strDrivenerRelation = value;}
        }

        
#endregion


        
#region 构造函数
        
public CNoFlashDownList()
        
{}
        
#endregion


        
#region 实现初始化下拉列表框

        
//得到下拉列表选定值所在数据源行的行号
        private int GetSelectRowID(DropDownList ddl)
        
{
            
string strValueFiled = ddl.DataValueField;
            
string strSelectValue =    ddl.SelectedValue.ToString();

            DataView dv 
= new DataView((DataTable)(ddl.DataSource));
            dv.Sort 
= strValueFiled;

            
return dv.Find(strSelectValue);
        }


        
/// <summary>
        
/// 注册下拉列表,添加客户端脚本
        
/// </summary>
        
/// <param name="driver">驱动方下拉列表</param>
        
/// <param name="drivener">从动方下拉列表</param>
       
public void RegisterDropDownList(DropDownList driver,DropDownList drivener)
        
{
            
//取得准备数据
            ddlDriver    = driver;
            ddlDrivener 
= drivener;

            strDriverTextField 
= ddlDriver.DataTextField;
            strDriverValueField 
= ddlDriver.DataValueField;

            strDrivenerTextField 
= ddlDrivener.DataTextField;
            strDrivenerValueField 
= ddlDrivener.DataValueField;

            dtDriver 
= (DataTable)(ddlDriver.DataSource);
            dtDrivener 
= (DataTable)(ddlDrivener.DataSource);

            
//获取选定值,并过滤从动下拉列表的数据
            int iIndex = GetSelectRowID(ddlDriver);

            DataRow drFilter 
= dtDriver.Rows[iIndex];
            
string strRelate = drFilter[strDriverRelation].ToString().Trim();

            DataView dv 
= new DataView(dtDrivener);
            dv.RowFilter 
= strDriverRelation + "='"+strRelate+"'";

            ddlDrivener.Items.Clear();
            ddlDrivener.DataSource 
= dv;
            ddlDrivener.DataTextField 
= strDrivenerTextField;
            ddlDrivener.DataValueField 
= strDrivenerValueField;
            ddlDrivener.DataBind();
            
            
//加入客户端脚本-初始化部分
            string CilentScript = @" <script language=""javascript"">
            
            var countDriver;
            var countDrivener;

            countDriver=0;
            countDrivener=0;

            ArrayDriver = new Array();
            ArrayDrivener = new Array();
";

            
//初始化数组值,并加入客户端脚本
            DataRow drDriver = null;
            
for(int i = 0;i <dtDriver.Rows.Count ;i++)
            
{
                drDriver 
= dtDriver.Rows[i];
                CilentScript 
+= String.Format("ArrayDriver[countDriver++] = new Array(\"{0}\",\"{1}\",\"{2}\");\n", drDriver[strDriverValueField].ToString(),drDriver[strDriverTextField].ToString(), drDriver[strDriverRelation].ToString());
            }


            DataRow drDrivener 
= null;
            
for(int i = 0;i <dtDrivener.Rows.Count ;i++)
            
{
                drDrivener 
= dtDrivener.Rows[i];
                CilentScript 
+= String.Format("ArrayDrivener[countDrivener++] = new Array(\"{0}\",\"{1}\",\"{2}\");\n", drDrivener[strDrivenerValueField].ToString(),drDrivener[strDrivenerTextField].ToString(), drDrivener[strDrivenerRelation].ToString());
            }


            
//注册驱动下拉列表的项改变事件
            string ddlDriverID = ddlDriver.ID.ToString().Trim();
            
string ddlDrivenerID = ddlDrivener.ID.ToString().Trim();

            ddlDriver.Attributes[
"onchange"= "javascript:changedownlist(document.Form1," + ddlDriverID + "," + ddlDrivenerID + ");";

            
//加入客户端脚本-连动部分
            CilentScript += @"        
            function changedownlist(myfrm,Driver,Drivener)
            {
                var SelectedBigId,i,j,SelectDataType;
                
                for (i= Drivener.options.length-1;i>=0 ;--i)      
                {
                    Drivener.options[i] = null; 
                }
            
                SelectedBigId = Driver.options[Driver.selectedIndex].value;
            
                for (i=0;i<ArrayDriver.length;i++)
                {
                    if (SelectedBigId == ArrayDriver[i][0])
                    {
                        SelectDataType = ArrayDriver[i][2];
                        break;
                    }
                }
            
                j = 0;    
                
                for (i=0 ;i< ArrayDrivener.length ;i++)      
                {
                    if (SelectDataType == ArrayDrivener[i][2])
                    {
                        Drivener.options[j] = new Option(ArrayDrivener[i][1],ArrayDrivener[i][0]); 
                        ++j;
                    }
                }
            }
            </script>
";

            
//将脚本写入客户端
            HttpContext.Current.Response.Write(CilentScript);
        }

       
#endregion

       
    }

}

2.使用方法,附测试源码:
首先是取一对DropDownList控件的数据源,并绑定它们
接着当然是实例化类CNoFlashDownList了,如果用的多可以考虑封成静态的
然后是指定它们各自用于连动的关系列,这里暴露的两个属性DriverRelation和DrivenerRelation
uc.DriverRelation = "DataType";
uc.DrivenerRelation = "DataType";
最后是调用RegisterDropDownList方法注册控件了

测试的代码

protected System.Web.UI.WebControls.DropDownList ddlDrivener;
        
protected System.Web.UI.WebControls.DropDownList ddlDriver;
    
        
private void Page_Load(object sender, System.EventArgs e)
        
{
            
if (!IsPostBack)
            
{
                DataTable dtType 
= new DataTable();
                dtType.Columns.Add(
"TypeCode");
                dtType.Columns.Add(
"TypeName");
                dtType.Columns.Add(
"DataType");

                DataTable dtValue 
= new DataTable("MyTable");

                dtValue.Columns.Add(
"ValueCode");
                dtValue.Columns.Add(
"ValueName");
                dtValue.Columns.Add(
"DataType");

                DataRow Dr 
= dtType.NewRow();
                Dr[
"TypeCode"= "AllMoney";
                Dr[
"TypeName"= "应发工资";
                Dr[
"DataType"= "Num";
                dtType.Rows.Add(Dr);

                DataRow Dr1 
= dtType.NewRow();
                Dr1[
"TypeCode"= "Uid";
                Dr1[
"TypeName"= "身份证号码";
                Dr1[
"DataType"= "Char";
                dtType.Rows.Add(Dr1);

                DataRow Dr2 
= dtType.NewRow();
                Dr2[
"TypeCode"= "Worker";
                Dr2[
"TypeName"= "行政职务";
                Dr2[
"DataType"= "Meg";
                dtType.Rows.Add(Dr2);
                
                
//开始添加第二个表中的内容
                DataRow Dr3 = dtValue.NewRow();
                Dr3[
"ValueCode"= "=";
                Dr3[
"ValueName"= "等于";
                Dr3[
"DataType"= "Num";
                dtValue.Rows.Add(Dr3);

                DataRow Dr4 
= dtValue.NewRow();
                Dr4[
"ValueCode"= "<>";
                Dr4[
"ValueName"= "不等于";
                Dr4[
"DataType"= "Char";
                dtValue.Rows.Add(Dr4);

                DataRow Dr5 
= dtValue.NewRow();
                Dr5[
"ValueCode"= "like";
                Dr5[
"ValueName"= "相似";
                Dr5[
"DataType"= "Char";
                dtValue.Rows.Add(Dr5);

                DataRow Dr6 
= dtValue.NewRow();
                Dr6[
"ValueCode"= ">";
                Dr6[
"ValueName"= "大于";
                Dr6[
"DataType"= "Num";
                dtValue.Rows.Add(Dr6);


                DataRow Dr7 
= dtValue.NewRow();
                Dr7[
"ValueCode"= "=";
                Dr7[
"ValueName"= "不等于";
                Dr7[
"DataType"= "Meg";
                dtValue.Rows.Add(Dr7);

                DataRow Dr8 
= dtValue.NewRow();
                Dr8[
"ValueCode"= "=";
                Dr8[
"ValueName"= "等于";
                Dr8[
"DataType"= "Meg";
                dtValue.Rows.Add(Dr8); 

                CNoFlashDownList uc 
= new CNoFlashDownList();

                ddlDriver.DataSource 
= dtType;
                ddlDriver.DataTextField 
= "TypeName";
                ddlDriver.DataValueField 
= "TypeCode";
                ddlDriver.DataBind();

                ddlDriver.SelectedIndex 
= 2;

                ddlDrivener.DataSource 
= dtValue;
                ddlDrivener.DataTextField 
="ValueName";
                ddlDrivener.DataValueField 
= "ValueCode";
                ddlDrivener.DataBind();

                uc.DriverRelation 
= "DataType";
                uc.DrivenerRelation 
= "DataType";

                uc.RegisterDropDownList(ddlDriver,ddlDrivener);
                }

        }

3.存在的问题
上面的实现在一个页面只有一对连动的DropDownList控件时完全满足需求,但是如果出现并注册多对时就会产生紊乱了,后来想到重载RegisterDropDownList方法,加一个唯一区别的对标识,重复写段带区别的脚本到客户端,但是还是感觉有点土,因为会重复出现一些类似的脚本,违背了xp编程原则;

希望有兴趣的同仁,对上面的实现,以及我提出的问题提点意见和解决方案,先谢谢了……

下载:NoRefreshJointDDL.rar

posted @ 2005-07-08 13:23  冰戈  阅读(5762)  评论(21编辑  收藏  举报