因为网站需要,在网上找了很多都不满足需要,所以找了一个代码自己修改,然后再封装成自定义控件。自己觉得还比较满意,希望有人需要可以供查询。
控件的特点:1、理论上支持无限级,不过我目前只做到4级,需要的人可自行拓展,很简单的:)。2、是数据库版的,也可以很方便的改为XML版本。3、加载速度比较快。4、可以设置初始值(很多没这个功能哦)。5、可以设置是否必须选择。6、可以设置是否必须选择到最后一级。7、等你去发现……================== 控件代码 =====================using System;using System.Data;using System.Web.UI;using System.Web.UI.WebControls;using System.ComponentModel; namespace StsProject.CustomControl{ [DefaultProperty("Text"), Designer(typeof(CompanyIndustryDesigner)), ToolboxData("<{0}:CompanyIndustryer runat=server></{0}:CompanyIndustryer>")] public class CompanyIndustryer : System.Web.UI.WebControls.WebControl,INamingContainer { private bool _ismust = false; private bool _musttoend = false;[Bindable(true),
Category("Behavior"), DefaultValue(false), Description("是否必须填写")] public bool IsMust { get{return _ismust;} set{_ismust=value;} }[Bindable(true),
Category("Behavior"), DefaultValue(false), Description("是否必须选择到最后一级")] public bool MustToEnd { get{return _musttoend;} set{_musttoend=value;} } [Bindable(true), Category("Behavior"), DefaultValue(""), Description("行业编号")] public string IndustryValue { set { this.EnsureChildControls(); ((TextBox)Controls[0]).Text = value; } get { this.EnsureChildControls(); return ((TextBox)Controls[0]).Text; } }protected override void CreateChildControls()
{ base.CreateChildControls ();TextBox txtIndustryValue = new TextBox();
txtIndustryValue.ID = "IndustryValue"; txtIndustryValue.Width = 0; this.Controls.Add(txtIndustryValue);DropDownList dropIndustry1 = new DropDownList();
dropIndustry1.ID = "dropIndustry1"; this.Controls.Add(dropIndustry1);DropDownList dropIndustry2 = new DropDownList();
dropIndustry2.ID = "dropIndustry2"; this.Controls.Add(dropIndustry2);DropDownList dropIndustry3 = new DropDownList();
dropIndustry3.ID = "dropIndustry3"; this.Controls.Add(dropIndustry3);DropDownList dropIndustry4 = new DropDownList();
dropIndustry4.ID = "dropIndustry4"; dropIndustry4.Width = 0; this.Controls.Add(dropIndustry4);TextBox txtToEnd = new TextBox();
txtToEnd.ID = "txtIfEnd"; txtToEnd.Width = 0; this.Controls.Add(txtToEnd); dropIndustry1.Attributes.Add("ChildSelectName", dropIndustry2.ClientID); dropIndustry1.Attributes.Add("style","display:none"); dropIndustry2.Attributes.Add("ChildSelectName", dropIndustry3.ClientID); dropIndustry2.Attributes.Add("FatherSelectName", dropIndustry1.ClientID); dropIndustry2.Attributes.Add("style","display:none"); dropIndustry3.Attributes.Add("ChildSelectName", dropIndustry4.ClientID); dropIndustry3.Attributes.Add("FatherSelectName", dropIndustry2.ClientID); dropIndustry3.Attributes.Add("style","display:none");if (_ismust)
{ RequiredFieldValidator valrIndustry = new RequiredFieldValidator(); valrIndustry.ControlToValidate = txtIndustryValue.ID; valrIndustry.ErrorMessage = "<<请选择分类"; valrIndustry.Display = ValidatorDisplay.Dynamic; this.Controls.Add(valrIndustry); }if (_musttoend)
{ RegularExpressionValidator valeIndustry = new RegularExpressionValidator(); valeIndustry.ControlToValidate = txtToEnd.ID; valeIndustry.ErrorMessage = "<<必须选择到最后一级"; valeIndustry.Display = ValidatorDisplay.Dynamic; valeIndustry.ValidationExpression = "Yes|DD"; this.Controls.Add(valeIndustry); }string strScript = @"<script>
var m_oXMLDoc = new ActiveXObject(""Microsoft.XMLDOM""); var m_sBaseSrc = ""/GetIndustry.aspx?TopID="";function BindSelect( strXMLSrc , objSelectName, defaultVal)
{ m_oXMLDoc.async = true; m_oXMLDoc.onreadystatechange = Function( ""fnLoadComplete('"" + objSelectName + ""', '"" + defaultVal + ""');"" ); m_oXMLDoc.load( strXMLSrc ); } function fnLoadComplete(objSelectName, defaultVal) { var objSelect = document.all[objSelectName]; var aryXMLNodes; var node; if (objSelect == null) return; try { var iReadyState = m_oXMLDoc.readyState; } catch(e) { return; } if( iReadyState != 4 ) return; if( m_oXMLDoc != null && m_oXMLDoc.xml != """" ) { objSelect.length = 0; aryXMLNodes = m_oXMLDoc.documentElement.selectNodes(""//IndustryList/Table""); objSelect.options[0] = new Option(""==请选择=="",""""); var m=0; for (var i=0; i < aryXMLNodes.length; i++) { node = aryXMLNodes[i]; objSelect.options[i+1] = new Option(aryXMLNodes[i].childNodes.item(1).text, aryXMLNodes[i].childNodes.item(0).text); m=m+1; } if (m!=0) { objSelect.style.display=''; } else { objSelect.style.display='none'; }if (defaultVal != null && defaultVal != """" && objSelect.length > 1)
{ SetSelectedValue(objSelect, defaultVal) } if(objSelect.ChildSelectName != null) { objSelect.onchange = Function( ""BindSelect(m_sBaseSrc+this.options[this.selectedIndex].value, '""+objSelect.ChildSelectName+""', '""+defaultVal+""');SetTheValue(this);"" ); objSelect.fireEvent(""onchange""); } else { objSelect.onchange = Function( ""var val = this.options[this.selectedIndex].value;if(val!='')document.all."+ txtIndustryValue.ClientID ;"" ); } } }
function SetTheValue(obj)
{ //这个地方代码很多,主要是修复我找的代码的一个缺陷,就是选择了一级后,然后再选则该级的最上一个选项(--请选择--)后,取到的值不变 var val = obj.value;if(val!='')
document.all."+ txtIndustryValue.ClientID ; else { if(obj.FatherSelectName!=null && document.all[obj.FatherSelectName]) { if(document.all[obj.FatherSelectName].value!='') document.all."+ txtIndustryValue.ClientID ; else { if(document.all[obj.FatherSelectName].FatherSelectName!=null && document.all[document.all[obj.FatherSelectName].FatherSelectName]) { if(document.all[document.all[obj.FatherSelectName].FatherSelectName].value!='') document.all."+ txtIndustryValue.ClientID ; else document.all."+ txtIndustryValue.ClientID ; } else document.all."+ txtIndustryValue.ClientID ; } } else document.all."+ txtIndustryValue.ClientID ; } //这里做得比较死。不过我没找到最好的办法,如果有好的办法,别忘记告诉我哦 if(document.all."+ dropIndustry1.ClientID + @".value=='') document.all."+ txtToEnd.ClientID = ""DD""; else if(document.all."+ dropIndustry2.ClientID + @".value=='' || (document.all."+ dropIndustry3.ClientID + @".value=='' && document.all."+ dropIndustry3.ClientID + @".length>1)) document.all."+ txtToEnd.ClientID = ""No""; else document.all."+ txtToEnd.ClientID = ""Yes""; } function InitSelect(defaultVal) { //document.all."+ txtIndustryValue.ClientID = """"; BindSelect( m_sBaseSrc + ""000"", """+ dropIndustry1.ClientID +@""", defaultVal); }function Equality(val1,val2)
{ if (val1.length < val2.length || val2 == """") return false; return (val1.substr(0,val2.length) == val2) }function SetSelectedValue(oSel,val)
{ if (val == null) return; for(var i=0; i<oSel.length; i++) { if (Equality(val, oSel.options[i].value)) { oSel.selectedIndex = i;if(oSel.ChildSelectName == null)
oSel.fireEvent(""onchange""); break; } } }function DoValue()
{ if(document.all." + txtIndustryValue.ClientID + @") { InitSelect(document.all."+ txtIndustryValue.ClientID ); } }window.onload = function(){DoValue();}
</script>";
Page.RegisterClientScriptBlock("TheScript",strScript);
} }}/// <summary>
/// 设计器/// </summary>public class CompanyIndustryDesigner : System.Web.UI.Design.ControlDesigner{ public override string GetDesignTimeHtml() { return "<select><option>请选择分类..</option></select>"; }}================== GetIndustry.aspx 代码 ===================== private void Page_Load(object sender, System.EventArgs e) { string TopID; if (Request.QueryString["TopID"]==null) TopID = "000"; else TopID = Request.QueryString["TopID"]; CompanyStore store = new CompanyStore(); DataSet ds = store.GetIndustryByTopID("IndustryList", TopID);XmlTextWriter writer = new XmlTextWriter(Response.OutputStream, System.Text.Encoding.GetEncoding("utf-8"));
writer.Formatting = Formatting.Indented; writer.Indentation = 4; writer.IndentChar = ' '; ds.WriteXml(writer); writer.Flush(); writer.Close(); ds.Dispose(); Response.End(); }================== 数据库结构 和 存储过程 =======================indu_id varchar 9 0 编号(非自动,下级包含上级编号)indu_name varchar 50 0 名称indu_topid varchar 9 0 上级IDindu_order tinyint 1 0 排序SELECT * FROM Industry WHERE ORDER BY indu_order asc