大家应该都处理过网页上多级DropDownList无刷新联动问题。
大家基本的实现方式:
1、使用XML技术
2、使用Ajax技术
3、使用JavaScript技术
前些天用JavaScript和C#写一个通用的类(当然也借鉴了别人写的),基本功能已经实现了。
源代码: Top
using System;
using System.Data;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Utility.Web.UI.MyCustomControls.DropDownList
{
/// <summary>
/// 功能:设置DropDownList的多级无刷新联动
///
/// 前提:1、已经为DropDownList设置DataSource(DataTable类型数据)
/// 2、DataSource需含有“驱动方”和“从动方”的关联字段
///
/// 步骤:1、实例化对象
/// 2、注册准备(可多次准备)
/// 3、注册完成(只能一次完成)
/// 4、注册联动事件
///
/// 注意:
/// </summary>
public class Linkage
{
/// <summary>
/// 构造函数,初始化
/// </summary>
public Linkage()
{
CilentScript = @"<script language=""javascript""> {0} {1} </script>";
CilentScript = System.String.Format(CilentScript,"RegisterScriptoylb",GetFunctionCilentScript());
}
#region 私有变量
private string CilentScript = "";
private string RegisterScript = "";
#endregion
#region 私有方法
/// <summary>
/// 获取DropDownList初始化数组脚本
/// </summary>
/// <param name="ddl">DropDownList</param>
/// <param name="driverRelation">DriverRelation</param>
/// <returns></returns>
private string GetInitArrayScript(System.Web.UI.WebControls.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 = System.String.Format(strRegisterScript+" /n",strCount,strArray);
//初始化数组值
DataRow drDriver = null;
for(int i = 0;i <dtSource.Rows.Count ;i++)
{
drDriver = dtSource.Rows[i];
strRegisterScript += System.String.Format(strArray+"["+strCount+"++] = new Array(/"{0}/",/"{1}/",/"{2}/");/n", drDriver[strValueField].ToString(),drDriver[strTextField].ToString(), drDriver[strRelation].ToString());
}
return strRegisterScript;
}
/// <summary>
/// 得到事件函数脚本
/// </summary>
/// <returns></returns>
private string GetFunctionCilentScript()
{
string strScript = @"
function changedownlist(Driver,ArrayDriver,Drivener,ArrayDrivener)
{
var SelectedBigId,i,j,Relation;
var DrivenerLn = Drivener.options.length;
var DriverSelectedIndex = Driver.selectedIndex;
//清空“从动方”数据
while(DrivenerLn--)
{
Drivener.options[DrivenerLn] = null;
}
//取得关联列的值
if(DriverSelectedIndex!=-1) //驱动方有数据
{
SelectedBigId = Driver.options[DriverSelectedIndex].value;
for (i=0;i<ArrayDriver.length;i++)
{
if (SelectedBigId == ArrayDriver[i][0])
{
Relation = ArrayDriver[i][0];
break;
}
}
//重新加载“从动方”数据
j = 0;
for (i=0 ;i< ArrayDrivener.length ;i++)
{
if (Relation == ArrayDrivener[i][2])
{
Drivener.options[j] = new Option(ArrayDrivener[i][1],ArrayDrivener[i][0]);
j++;
}
}
}
}";
return strScript;
}
/// <summary>
/// 写入脚本
/// </summary>
private void WriteScriptToCilent()
{
//去掉占位字符串
string strCilentScript = CilentScript.Replace("RegisterScriptoylb","");
//将脚本写入客户端
HttpContext.Current.Response.Write(strCilentScript);
}
/// <summary>
/// 根据驱动方选择的项,初始化从动方数据
/// </summary>
/// <param name="driver"></param>
/// <param name="driverRelation"></param>
/// <param name="drivener"></param>
/// <param name="drivenerRelation"></param>
private void InitDrivener(System.Web.UI.WebControls.DropDownList driver,string driverRelation,System.Web.UI.WebControls.DropDownList drivener,string drivenerRelation)
{
//取得“从动方”数据源
DataTable dsDrivener = (DataTable)(drivener.DataSource);
//获取选定值,并过滤从动下拉列表的数据
string strDriverSelectedValue = driver.SelectedValue;
DataView dv = new DataView(dsDrivener);
dv.RowFilter = drivenerRelation + "='"+strDriverSelectedValue+"'";
drivener.Items.Clear();
drivener.DataSource = dv;
drivener.DataTextField = drivener.DataTextField;;
drivener.DataValueField = drivener.DataValueField;
drivener.DataBind();
}
#endregion
#region 公共方法
/// <summary>
/// 【注册准备】 注册需联动的下拉列表(可以进行多次)
/// </summary>
/// <param name="driver">驱动方</param>
/// <param name="driverRelation">驱动方关系列</param>
/// <param name="drivener">从动方</param>
/// <param name="drivenerRelation">从动方关系列</param>
/// <param name="isOnlyPrepareDrivener">是否只对从动方进行注册准备</param>
public void RegisterObjectPrepare(System.Web.UI.WebControls.DropDownList driver,string driverRelation,System.Web.UI.WebControls.DropDownList drivener,string drivenerRelation,bool isOnlyPrepareDrivener)
{
if(!isOnlyPrepareDrivener)
{
RegisterScript += GetInitArrayScript(driver,driverRelation);
}
RegisterScript += GetInitArrayScript(drivener,drivenerRelation);
//初始化“从动方”数据
InitDrivener(driver,driverRelation,drivener,drivenerRelation);
}
/// <summary>
/// 【注册完成】 注册需联动的下拉列表(只能进行一次)
/// </summary>
public void RegisterObjectComplete()
{
//这里使用“RegisterScriptoylb”继续占位,留予下次注册下拉列表,最后注册脚本时将清除
CilentScript = CilentScript.Replace("RegisterScriptoylb","RegisterScriptoylb "+RegisterScript);
WriteScriptToCilent();
}
/// <summary>
/// 注册联动事件
/// </summary>
/// <param name="driver">驱动方=注册目标</param>
/// <param name="drivener">从动方</param>
public void RegisterEvent(System.Web.UI.WebControls.DropDownList driver,System.Web.UI.WebControls.DropDownList drivener)
{
string ddlDriverID = driver.ID.ToString().Trim();
string ddlDrivenerID = drivener.ID.ToString().Trim();
driver.Attributes["onchange"] += "javascript:changedownlist(document.all." + ddlDriverID + ",Array"+ddlDriverID+",document.all." + ddlDrivenerID + ",Array"+ddlDrivenerID+");";
}
/// <summary>
/// 注册联动事件(重载)
/// </summary>
/// <param name="registerObject">注册目标</param>
/// <param name="driver">驱动方</param>
/// <param name="drivener">从动方</param>
public void RegisterEvent(System.Web.UI.WebControls.DropDownList registerObject,System.Web.UI.WebControls.DropDownList driver,System.Web.UI.WebControls.DropDownList drivener)
{
string ddlDriverID = driver.ID.ToString().Trim();
string ddlDrivenerID = drivener.ID.ToString().Trim();
registerObject.Attributes["onchange"] += "javascript:changedownlist(document.all." + ddlDriverID + ",Array"+ddlDriverID+",document.all." + ddlDrivenerID + ",Array"+ddlDrivenerID+");";
}
#endregion
}//end class
}//end namespace
事例: Top
下面是例子的一部分,结合了三层模式开发
数据层:
using System;
using System.Data;
using Utility.Data;
namespace WebApplication1.Data
{
/// <summary>
/// Case 的摘要说明。
/// </summary>
public class Case:MsAccess
{
private string sql; //sql语句变量
public Case()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
public DataTable Province()
{
sql = "";
sql = sql + " select provinceId as Value1,province as Text1,provinceId as Relation1 from province ";
return ReturnDataTable(sql);
}
public DataTable City()
{
sql = "";
sql = sql + " select cityID as Value2,city as Text2,father as Relation2 from city ";
return ReturnDataTable(sql);
}
public DataTable Area()
{
sql = "";
sql = sql + " select areaID as Value3,area as Text3,father as Relation3 from area ";
return ReturnDataTable(sql);
}
}
}
商务层:
using System;
using System.Data;
using Utility.Data;
namespace WebApplication1.Business
{
/// <summary>
/// Case 的摘要说明。
/// </summary>
public class Case
{
Data.Case linkage = new Data.Case();
public Case()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
public DataTable Province()
{
return linkage.Province();
}
public DataTable City()
{
return linkage.City();
}
public DataTable Area()
{
return linkage.Area();
}
}
}
表示层:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
using Utility.Web.UI.MyCustomControls.DropDownList;
namespace WebApplication1
{
/// <summary>
/// Test 的摘要说明。
/// </summary>
public class NoRefreshCase : System.Web.UI.Page
{
protected System.Web.UI.WebControls.DropDownList DropDownList1;
protected System.Web.UI.WebControls.DropDownList DropDownList2;
protected System.Web.UI.WebControls.DropDownList DropDownList3;
protected System.Web.UI.WebControls.Button Button1;
Business.Case linkage = new Business.Case();
private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
{
//设置数据源
DataBind1();
DataBind2();
DataBind3();
Linkage lk = new Linkage(); //实例化对象
lk.RegisterObjectPrepare(DropDownList1,"Relation1",DropDownList2,"Relation2",false); //注册联动关系
lk.RegisterObjectPrepare(DropDownList2,"Relation2",DropDownList3,"Relation3",true); //注册联动关系,只注册“从动方”
lk.RegisterObjectComplete();
lk.RegisterEvent(DropDownList1,DropDownList2); //注册联动事件
lk.RegisterEvent(DropDownList1,DropDownList2,DropDownList3); //注册联动事件
lk.RegisterEvent(DropDownList2,DropDownList3); //注册联动事件
}
}
#region 邦定数据
private void DataBind1()
{
DropDownList1.DataSource = linkage.Province();
DropDownList1.DataTextField = "Text1";
DropDownList1.DataValueField = "Value1";
DropDownList1.DataBind();
}
private void DataBind2()
{
DropDownList2.DataSource = linkage.City();
DropDownList2.DataTextField = "Text2";
DropDownList2.DataValueField = "Value2";
DropDownList2.DataBind();
}
private void DataBind3()
{
DropDownList3.DataSource = linkage.Area();
DropDownList3.DataTextField = "Text3";
DropDownList3.DataValueField = "Value3";
DropDownList3.DataBind();
}
#endregion
#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.ID = "NoRefreshCase";
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
}
}
因为没有空间、同时有数据库,所以没上传,有需要的朋友请留下Email ,如大家有好的改进意见请留下。