[报到] 发布个自己修改的联动下拉菜单 (无限级、数据库、初始值.)

因为网站需要,在网上找了很多都不满足需要,所以找了一个代码自己修改,然后再封装成自定义控件。自己觉得还比较满意,希望有人需要可以供查询。

控件的特点:
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 +@".value=val;"" );   
     }
    }
   }

 

   function SetTheValue(obj)
   {
    //这个地方代码很多,主要是修复我找的代码的一个缺陷,就是选择了一级后,然后再选则该级的最上一个选项(--请选择--)后,取到的值不变
    var val = obj.value;

    if(val!='')
     document.all."+ txtIndustryValue.ClientID +@".value=val;
    else
    {
     if(obj.FatherSelectName!=null && document.all[obj.FatherSelectName])
     {
      if(document.all[obj.FatherSelectName].value!='')
       document.all."+ txtIndustryValue.ClientID +@".value=document.all[obj.FatherSelectName].value;
      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 +@".value=document.all[document.all[obj.FatherSelectName].FatherSelectName].value;
        else
         document.all."+ txtIndustryValue.ClientID +@".value='';
       }
       else
        document.all."+ txtIndustryValue.ClientID +@".value='';
      }
     }
     else
      document.all."+ txtIndustryValue.ClientID +@".value='';
    }


    //这里做得比较死。不过我没找到最好的办法,如果有好的办法,别忘记告诉我哦
    if(document.all."+ dropIndustry1.ClientID + @".value=='')
     document.all."+ txtToEnd.ClientID +@".value= ""DD"";
    else if(document.all."+ dropIndustry2.ClientID + @".value=='' || (document.all."+ dropIndustry3.ClientID + @".value=='' && document.all."+ dropIndustry3.ClientID + @".length>1))
     document.all."+ txtToEnd.ClientID +@".value= ""No"";
    else
     document.all."+ txtToEnd.ClientID +@".value= ""Yes"";
   }


   function InitSelect(defaultVal)
   {
    //document.all."+ txtIndustryValue.ClientID +@".value = """";
    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 +@".value);
    }
   }

   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    上级ID
indu_order        tinyint       1         0    排序

SELECT * FROM Industry  WHERE coin_topid=@TopID ORDER BY indu_order asc




posted @ 2005-07-31 10:18  子扬's Blog  阅读(3266)  评论(12编辑  收藏  举报