冰戈--真诚的平凡

世界上不可能时时处处都有惊天动地的美丽,但平凡的美丽随处可见,而注入真诚的平凡则具有钻石般永恒的光泽
posts - 181, comments - 1800, trackbacks - 67, articles - 32
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

近期由于项目需要实现大量的无刷新的连动下拉列表,感觉每个页面都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

Feedback

#1楼   回复  引用  查看    

2005-07-08 12:02 by 补丁      
希望能够实现多级联动啊
:>

#2楼   回复  引用    

2005-07-08 13:29 by try[未注册用户]
测试代码好像没完成哦

#3楼[楼主]   回复  引用  查看    

2005-07-08 13:35 by 冰戈      
@ 补丁
这两天就会更新一个版本出来,解决多级连动和现存的问题
@try
是blog出问题了,更新了下就丢了很多东西,郁闷的很,现在好了

#4楼   回复  引用  查看    

2005-07-08 14:21 by dudu      
blog出了什么问题?

#5楼[楼主]   回复  引用  查看    

2005-07-08 14:28 by 冰戈      
@dudu
我更新的时候,加下载源码的链接,转到html格式下面改链接的显示格式,弹出一个对话框,我没在意继续改了,更新,速度奇慢,关了重来就丢东西了,还好有备份,心慌慌

而且更新时浏览器报错“磁盘已满”,请问是不是有这个毛病?

#6楼   回复  引用  查看    

2005-07-08 14:32 by dudu      
@冰戈
没遇到过这个问题。可能是你所用浏览器的问题。
你可以通过“恢复上次提交”恢复上次提交的内容。

#7楼[楼主]   回复  引用  查看    

2005-07-08 14:33 by 冰戈      
@dudu
我更新的时候,加下载源码的链接,转到html格式下面改链接的显示格式,弹出一个对话框,我没在
意继续改了,更新,速度奇慢,关了重来就丢东西了,还好有备份,心慌慌


而且更新时浏览器报错“磁盘已满”,请问是不是有这个毛病?

#8楼   回复  引用  查看    

2005-07-08 15:32 by 补丁      
哈哈,好
就等你这个啦
不收费吧:>

#9楼[楼主]   回复  引用  查看    

2005-07-08 15:40 by 冰戈      
@ 补丁
呵呵,这么个小东西,还敢收费?
完全是出于交流学习的目的

#10楼   回复  引用    

2005-07-08 18:37 by happyprogram
不错,等正式版本,呵呵

#11楼   回复  引用    

2005-07-10 22:20 by qq7good[未注册用户]
是不是加上runat = server
否则一涮新页面选择的选项就复原了。

期待一个页面多组空间的版本

#12楼[楼主]   回复  引用  查看    

2005-07-11 14:40 by 冰戈      

#13楼   回复  引用    

2005-07-11 15:34 by sunrise[未注册用户]
还嫰着。。。。。。

#14楼[楼主]   回复  引用  查看    

2005-07-11 16:08 by 冰戈      
@sunrise
是嫩,本来就是来求意见的嘛,呵呵
有什么见解,请直接留言,谢谢……

#15楼   回复  引用  查看    

2005-07-11 16:49 by kkding      
你要是封控件就kk了。哈哈

#16楼   回复  引用  查看    

2005-07-11 20:33 by alittlefish      
我以前也做过类似的一个东西,多级连动。不过没有花多久,也懒得优化代码。
http://www.lalashow.net/jm_tek/demo2.aspx" target="_blank">http://www.lalashow.net/jm_tek/demo2.aspx

#17楼   回复  引用    

2005-08-20 15:31 by 冷雪[未注册用户]
如果是物资编码,大约3万条记录,如何做?综合考虑以下速度

#18楼[楼主]   回复  引用  查看    

2005-08-20 22:50 by 冰戈      
to 冷雪
可以考虑使用ajax
http://hedonister.cnblogs.com/archive/2005/08/13/214022.html">http://hedonister.cnblogs.com/archive/2005/08/13/214022.html

#19楼   回复  引用    

2005-10-27 15:57 by gfdg[未注册用户]
private string strDriverRelation = ""; //关系列
那来的这个属性啊`???我怎么没找到的``????

#20楼   回复  引用    

2006-08-16 16:50 by Ajoy[未注册用户]
效果是很好,但是无法更新到数据库。



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 188420




相关文章:

相关链接: