《[分享]新封装的一个实现无刷新连动下拉列表类 》的改进版本
变化比较大:
1.改写方法的实现,降低函数的耦合度;
2.解决了上个post中提到的“注册多对下拉列表时就会产生紊乱”的问题;
3.暴露一个方法用于实现一拖n,多级联动问题,使用方法见测试代码;
一般情况下基本够用
下面是源码,欢迎拍砖
NoRefreshJointDDL2.cs
using System;
using System.Data;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace NoRefreshJointDDL
{
/// <summary>
///
/// </summary>
public class NoRefreshJointDDL2:System.Web.UI.Page
{
#region 成员变量
private string CilentScript;
private bool IsWrited = false;
#endregion
public NoRefreshJointDDL2()
{
CilentScript = @"<script language=""javascript""> {0} {1} </script>";
CilentScript = String.Format(CilentScript,"RegisterScriptoylb",GetFunctionCilentScript());
}
/// <summary>
/// 设置联动关系,通过暴露此方法来达到多级联动的目的,注意此处只能用于已注册的DropDownList
/// </summary>
/// <param name="driver">驱动方</param>
/// <param name="drivener">从动方</param>
public void SetDDLsRelation(DropDownList driver,DropDownList drivener)
{
string ddlDriverID = driver.ID.ToString().Trim();
string ddlDrivenerID = drivener.ID.ToString().Trim();
driver.Attributes["onchange"] = "javascript:changedownlist(document.Form1," + ddlDriverID + ",Array"+ddlDriverID+"," + ddlDrivenerID + ",Array"+ddlDrivenerID+");";
}
/// <summary>
/// 注册需联动的下拉列表
/// </summary>
/// <param name="driver">驱动方</param>
/// <param name="driverRelation">驱动方关系列</param>
/// <param name="drivener">从动方</param>
/// <param name="drivenerRelation">从动方关系列</param>
public void RegisterDropDownList(DropDownList driver,string driverRelation,DropDownList drivener,string drivenerRelation)
{
string strRegisterScript = GetInitArrayScript(driver,driverRelation);
strRegisterScript += GetInitArrayScript(drivener,drivenerRelation);
//这里使用“RegisterScriptoylb”继续占位,留予下次注册下拉列表,最后注册脚本时将清除
CilentScript = CilentScript.Replace("RegisterScriptoylb","RegisterScriptoylb "+strRegisterScript);
SetDDLsRelation(driver,drivener);
}
/// <summary>
/// 注册需联动的下拉列表
/// </summary>
/// <param name="driver">驱动方</param>
/// <param name="driverRelation">驱动方关系列</param>
/// <param name="drivener">从动方</param>
/// <param name="drivenerRelation">从动方关系列</param>
/// <param name="iswrite">是否直接写入客户端</param>
public void RegisterDropDownList(DropDownList driver,string driverRelation,DropDownList drivener,string drivenerRelation,bool iswrite)
{
RegisterDropDownList(driver,driverRelation,drivener,drivenerRelation);
if (iswrite)
{
WriteScriptToCilent();
IsWrited = true;
}
}
//获取初始化数组脚本
private string GetInitArrayScript(DropDownList ddl,string driverRelation)
{
//驱动部分
string strValueField = ddl.DataValueField; //编码列
string strTextField = ddl.DataTextField; //显示列
string strRelation = driverRelation; //关系列
//数据源
DataTable dtSource = (DataTable)(ddl.DataSource);
//组成变量
string ddlID = ddl.ID.ToString().Trim();
string strCount = "count"+ddlID;
string strArray = "Array"+ddlID;
string strRegisterScript = @"
var {0} = 0;
{1} = new Array();";
strRegisterScript = String.Format(strRegisterScript,strCount,strArray);
//初始化数组值
DataRow drDriver = null;
for(int i = 0;i <dtSource.Rows.Count ;i++)
{
drDriver = dtSource.Rows[i];
strRegisterScript += String.Format(strArray+"["+strCount+"++] = new Array(\"{0}\",\"{1}\",\"{2}\");\n", drDriver[strValueField].ToString(),drDriver[strTextField].ToString(), drDriver[strRelation].ToString());
}
return strRegisterScript;
}
//根据驱动方选择的项,初始化从动方数据
private void InitDrivener(DropDownList driver,string driverRelation,DropDownList drivener,string drivenerRelation)
{
//取得数据源
DataTable dtDriver = (DataTable)(driver.DataSource);
DataTable dtDrivener = (DataTable)(drivener.DataSource);
//获取选定值,并过滤从动下拉列表的数据
int iIndex = GetSelectRowID(driver);
DataRow drFilter = dtDriver.Rows[iIndex];
string strRelate = drFilter[driverRelation].ToString().Trim();
DataView dv = new DataView(dtDrivener);
dv.RowFilter = driverRelation + "='"+strRelate+"'";
drivener.Items.Clear();
drivener.DataSource = dv;
drivener.DataTextField = drivener.DataValueField;;
drivener.DataValueField = drivener.DataTextField;
drivener.DataBind();
}
//得到下拉列表选定值所在数据源行的行号
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);
}
//得到事件函数脚本
private string GetFunctionCilentScript()
{
string strScript = @"
function changedownlist(myfrm,Driver,ArrayDriver,Drivener,ArrayDrivener)
{
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;
}
}
}";
return strScript;
}
/// <summary>
/// 写入脚本
/// </summary>
public void WriteScriptToCilent()
{
if (IsWrited)
{
throw new Exception("自定义错误信息:重复写入客户端脚本,注册联动下拉列表失败!");
}
//去掉占位字符串
string strCilentScript = CilentScript.Replace("RegisterScriptoylb","");
//将脚本写入客户端
HttpContext.Current.Response.Write(strCilentScript);
}
}
}
using System.Data;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace NoRefreshJointDDL
{
/// <summary>
///
/// </summary>
public class NoRefreshJointDDL2:System.Web.UI.Page
{
#region 成员变量
private string CilentScript;
private bool IsWrited = false;
#endregion
public NoRefreshJointDDL2()
{
CilentScript = @"<script language=""javascript""> {0} {1} </script>";
CilentScript = String.Format(CilentScript,"RegisterScriptoylb",GetFunctionCilentScript());
}
/// <summary>
/// 设置联动关系,通过暴露此方法来达到多级联动的目的,注意此处只能用于已注册的DropDownList
/// </summary>
/// <param name="driver">驱动方</param>
/// <param name="drivener">从动方</param>
public void SetDDLsRelation(DropDownList driver,DropDownList drivener)
{
string ddlDriverID = driver.ID.ToString().Trim();
string ddlDrivenerID = drivener.ID.ToString().Trim();
driver.Attributes["onchange"] = "javascript:changedownlist(document.Form1," + ddlDriverID + ",Array"+ddlDriverID+"," + ddlDrivenerID + ",Array"+ddlDrivenerID+");";
}
/// <summary>
/// 注册需联动的下拉列表
/// </summary>
/// <param name="driver">驱动方</param>
/// <param name="driverRelation">驱动方关系列</param>
/// <param name="drivener">从动方</param>
/// <param name="drivenerRelation">从动方关系列</param>
public void RegisterDropDownList(DropDownList driver,string driverRelation,DropDownList drivener,string drivenerRelation)
{
string strRegisterScript = GetInitArrayScript(driver,driverRelation);
strRegisterScript += GetInitArrayScript(drivener,drivenerRelation);
//这里使用“RegisterScriptoylb”继续占位,留予下次注册下拉列表,最后注册脚本时将清除
CilentScript = CilentScript.Replace("RegisterScriptoylb","RegisterScriptoylb "+strRegisterScript);
SetDDLsRelation(driver,drivener);
}
/// <summary>
/// 注册需联动的下拉列表
/// </summary>
/// <param name="driver">驱动方</param>
/// <param name="driverRelation">驱动方关系列</param>
/// <param name="drivener">从动方</param>
/// <param name="drivenerRelation">从动方关系列</param>
/// <param name="iswrite">是否直接写入客户端</param>
public void RegisterDropDownList(DropDownList driver,string driverRelation,DropDownList drivener,string drivenerRelation,bool iswrite)
{
RegisterDropDownList(driver,driverRelation,drivener,drivenerRelation);
if (iswrite)
{
WriteScriptToCilent();
IsWrited = true;
}
}
//获取初始化数组脚本
private string GetInitArrayScript(DropDownList ddl,string driverRelation)
{
//驱动部分
string strValueField = ddl.DataValueField; //编码列
string strTextField = ddl.DataTextField; //显示列
string strRelation = driverRelation; //关系列
//数据源
DataTable dtSource = (DataTable)(ddl.DataSource);
//组成变量
string ddlID = ddl.ID.ToString().Trim();
string strCount = "count"+ddlID;
string strArray = "Array"+ddlID;
string strRegisterScript = @"
var {0} = 0;
{1} = new Array();";
strRegisterScript = String.Format(strRegisterScript,strCount,strArray);
//初始化数组值
DataRow drDriver = null;
for(int i = 0;i <dtSource.Rows.Count ;i++)
{
drDriver = dtSource.Rows[i];
strRegisterScript += String.Format(strArray+"["+strCount+"++] = new Array(\"{0}\",\"{1}\",\"{2}\");\n", drDriver[strValueField].ToString(),drDriver[strTextField].ToString(), drDriver[strRelation].ToString());
}
return strRegisterScript;
}
//根据驱动方选择的项,初始化从动方数据
private void InitDrivener(DropDownList driver,string driverRelation,DropDownList drivener,string drivenerRelation)
{
//取得数据源
DataTable dtDriver = (DataTable)(driver.DataSource);
DataTable dtDrivener = (DataTable)(drivener.DataSource);
//获取选定值,并过滤从动下拉列表的数据
int iIndex = GetSelectRowID(driver);
DataRow drFilter = dtDriver.Rows[iIndex];
string strRelate = drFilter[driverRelation].ToString().Trim();
DataView dv = new DataView(dtDrivener);
dv.RowFilter = driverRelation + "='"+strRelate+"'";
drivener.Items.Clear();
drivener.DataSource = dv;
drivener.DataTextField = drivener.DataValueField;;
drivener.DataValueField = drivener.DataTextField;
drivener.DataBind();
}
//得到下拉列表选定值所在数据源行的行号
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);
}
//得到事件函数脚本
private string GetFunctionCilentScript()
{
string strScript = @"
function changedownlist(myfrm,Driver,ArrayDriver,Drivener,ArrayDrivener)
{
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;
}
}
}";
return strScript;
}
/// <summary>
/// 写入脚本
/// </summary>
public void WriteScriptToCilent()
{
if (IsWrited)
{
throw new Exception("自定义错误信息:重复写入客户端脚本,注册联动下拉列表失败!");
}
//去掉占位字符串
string strCilentScript = CilentScript.Replace("RegisterScriptoylb","");
//将脚本写入客户端
HttpContext.Current.Response.Write(strCilentScript);
}
}
}
测试代码:
protected System.Web.UI.WebControls.DropDownList ddlDrivener;
protected System.Web.UI.WebControls.DropDownList ddlDriver2;
protected System.Web.UI.WebControls.DropDownList ddlDrivener2;
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);
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();
ddlDriver2.DataSource = dtType;
ddlDriver2.DataTextField = "TypeName";
ddlDriver2.DataValueField = "TypeCode";
ddlDriver2.DataBind();
ddlDriver2.SelectedIndex = 1;
ddlDrivener2.DataSource = dtValue;
ddlDrivener2.DataTextField ="ValueName";
ddlDrivener2.DataValueField = "ValueCode";
ddlDrivener2.DataBind();
NoRefreshJointDDL2 uc = new NoRefreshJointDDL2();
uc.RegisterDropDownList(ddlDriver,"DataType",ddlDrivener,"DataType");
uc.RegisterDropDownList(ddlDriver2,"DataType",ddlDrivener2,"DataType",true);
//--------------------下面设置可出现一拖二,多级连动效果,测试时可逐个设置
//设置出现一拖二
uc.SetDDLsRelation(ddlDriver,ddlDrivener2);
// //设置出现多级连动
// uc.SetDDLsRelation(ddlDriver,ddlDriver2);
}
protected System.Web.UI.WebControls.DropDownList ddlDriver2;
protected System.Web.UI.WebControls.DropDownList ddlDrivener2;
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);
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();
ddlDriver2.DataSource = dtType;
ddlDriver2.DataTextField = "TypeName";
ddlDriver2.DataValueField = "TypeCode";
ddlDriver2.DataBind();
ddlDriver2.SelectedIndex = 1;
ddlDrivener2.DataSource = dtValue;
ddlDrivener2.DataTextField ="ValueName";
ddlDrivener2.DataValueField = "ValueCode";
ddlDrivener2.DataBind();
NoRefreshJointDDL2 uc = new NoRefreshJointDDL2();
uc.RegisterDropDownList(ddlDriver,"DataType",ddlDrivener,"DataType");
uc.RegisterDropDownList(ddlDriver2,"DataType",ddlDrivener2,"DataType",true);
//--------------------下面设置可出现一拖二,多级连动效果,测试时可逐个设置
//设置出现一拖二
uc.SetDDLsRelation(ddlDriver,ddlDrivener2);
// //设置出现多级连动
// uc.SetDDLsRelation(ddlDriver,ddlDriver2);
}
源码下载:NoRefreshJointDDL2.0.rar