子扬's Blog
关注行业网站建设
posts - 6,  comments - 39,  trackbacks - 0

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

控件的特点:
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 on 2005-07-31 10:18 子扬's Blog 阅读(2293) 评论(12)  编辑 收藏 网摘 所属分类: 自定义控件

FeedBack:
2005-07-31 10:28 | chengulv      
楼主是不是能 提供一个demo下载, 这样能让大家更好的调试分析。

看这代码我都有点晕了。
  回复  引用  查看    
#2楼 [楼主]
2005-07-31 10:41 | ziyang [未注册用户]
demo可以在这里看到:
http://www.51bxg.com/test1.aspx
  回复  引用    
#3楼 [楼主]
2005-07-31 10:42 | ziyang [未注册用户]
demo的代码:
public class Test1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Label Label1;
protected sts2004.CustomControl.CompanyIndustryer CompanyIndustryer1;
protected System.Web.UI.WebControls.Button Button1;

private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
CompanyIndustryer1.IndustryValue = "002001002";
}



private void Button1_Click(object sender, System.EventArgs e)
{
Label1.Text = CompanyIndustryer1.IndustryValue;
}
}

  回复  引用    
2005-07-31 11:28 | 喜欢雨      
楼主能否把代码打包,提供下载啊~~~~
呵呵~~~
谢谢...
  回复  引用  查看    
2005-07-31 11:42 | 补丁      
在以前的应用中碰到几个问题:
1.不同的浏览器的问题(楼主这里肯定是问题,用了msxml)
2.第一级选择之后第三级(或者再靠后)没有消失,这里主要是js控制上的逻辑问题,似乎楼主的这个没有碰到问题,但是似乎反应比较慢,选择了第一级之后,后面的级次是在分析XML?如果数据量很大的话会不会延迟很久?
3.效率,生成js的效率,提供何种缓存机制(我做一个国家-地区-城市-县)的级连,从数据库取数据到生成一个这样的菜单得几秒钟,而这种菜单基本不变化,所以,提供一个缓存机制还是很有必要的

小弟js实在是菜,搞不了这东西,只能期待大家继续完善咯
另外,那个alittlefish的mddl(http://www.cnblogs.com/jmtek/archive/2005/03/13/117906.html)下载不下来了,哪位有这个控件传给我一份好么?
  回复  引用  查看    
2005-08-01 11:20 | Sadly_Lee      
哈哈,正好需要啊
  回复  引用  查看    
2005-08-01 14:32 | №阿儒№      
兄台
可否提供源码下载呀?
或者发一份给我?zhongru_tu@163.com
  回复  引用  查看    
#8楼 [楼主]
2005-08-01 16:19 | ziyang [未注册用户]
所有原代码都在文章中,就不用单独提供下载了吧。
  回复  引用    
2006-02-21 16:22 | 田敏 [未注册用户]
麻烦大侠给份源码参考下,不胜感激~
  回复  引用    
2006-03-28 18:58 | Bruce Lee      
怎么实现无限级啊,是不是还是要确定有多少级?
  回复  引用  查看    
2006-05-25 14:02 | fromciom [未注册用户]
楼主,非常感谢你。我找了很久了,终于在你这找到了,可是我现在海不知道怎么用。都哪几个文件,需要的运行环境是什么样的。我实在太菜了。还有我也象要一份打包的源码。fromciom@163.com谢谢啦 。
  回复  引用    
2006-12-11 17:44 | 45 [未注册用户]
東西確實是好東西,就是現在還不能使用。
能否再次提供demo或者將代碼打包發給我呢?
levin@gmail.com
非常感謝

  回复  引用    




标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2005-11-15 16:07 编辑过
Google站内搜索

相关文章:

相关链接:
 


<2005年7月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

与我联系

搜索

 

常用链接

留言簿(2)

随笔分类

随笔档案

.

最新随笔

最新评论

阅读排行榜

评论排行榜