控件开发(二级连动选择控件)

 

/// <summary>
/// Author:周海军
/// Date:2007-05-03
/// Content:二级连动选择控件
/// </summary>

我刚刚接触asp.net的时候,记的公司给我的任务是一个月内写一个电子商务网站。当时遇到了难题不少,其中记的有一个问题“省、市”连动选择。当时因为自己是刚刚接触.net,所以没有能用Ajax连动技术来实现“省、市”的选择,最后用的是:DropDownListAutoPostBack="True"。最近在网上看到有关“省市”连动的方法,不过是用Javascript来实现的。

   现在我把它做成一个控件,我们大家一起来学习。

      1. 此控件不仅仅是“省市”的连动选择,也可以来做其他有关的二级连动选择。
   直需要在Xml文件里来改写我门的二级连动信息文件。设置如下
                                                               
 

1.       控件的一些属性的设置:

            
 

1)。One_Name 是设置二级信息的第一级名称.
2)Two_Name 是设置二级信息的第二级名称
3)SiteMapXlFile 是设置二级信息的Xml文件的相对站点的路径.

          效果如下:
                           
 

现把源程序给出:希望多多提意见

       using System;

using System.Collections;

using System.Collections.Generic;

using System.Collections.Specialized;

using System.ComponentModel;

using System.IO;

using System.Text;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Xml;

 

namespace ZHJWebControls

{

    /// <summary>

    /// Author:周海军

    /// Date:2007-05-03

    /// Content:二级连动选择控件

    /// </summary>

    [DefaultProperty("Text"), ToolboxData("<{0}:ZHJPC runat=server></{0}:ZHJPC>"),

    System.Drawing.ToolboxBitmap(typeof(ZHJPC), "ZHJ_PC.bmp"),

    ParseChildren(true),

    PersistChildren(false)]

    public class ZHJPC : WebControl

    {

       

        #region 公共属性

        [Bindable(true),

        Category("Appearance"),

        DefaultValue("")]

        public string Text

        {

            get

            {

                if (ViewState["Text"] != null)

                {

                    return ViewState["Text"].ToString();

                }

                else

                {

                    return null;

                }

            }

            set

            {

                ViewState["Text"] = value;

            }

        }

 

        #endregion

 

        #region 扩展功能

 

       

 

        private string _sitemapxmlfile;

        /// <summary>

        /// Xml文件

        /// </summary>

        [Browsable(true)]

        [Description("SiteXmlFile")]

        [DefaultValue("")]

        [Category("扩展")]

        public virtual string SiteMapXmlFile

        {

            get { return _sitemapxmlfile; }

            set { _sitemapxmlfile = value; }

        }

 

        /// <summary>

        /// 一级名称

        /// </summary>

        private string _one_name="";

 

        [Browsable(true)]

        [Description("SiteXmlFile_OneName")]

        [DefaultValue("")]

        [Category("扩展")]

        public string One_Name

        {

            set

            {

                if (this._one_name != "" && this._two_name!=null)

                {

                   

                }

                _one_name = value;

            }

            get

            {

                return _one_name;

            }

        }

 

        /// <summary>

        /// 二级名称

        /// </summary>

        private string _two_name="";

        [Browsable(true)]

        [Description("SiteXmlFileTwoName")]

        [DefaultValue("")]

        [Category("扩展")]

        public string Two_Name

        {

            set

            {

                if (this._two_name != "" && this._two_name!=null)

                {

                    _two_name = value;

                }

               

            }

            get

            {

                return _two_name;

            }

        }

        #endregion

 

        //一级

        private ArrayList parr = new ArrayList();

        //二级

        private ArrayList carr = new ArrayList();

        //XmlFile名称

        private string SiteXmlFileName;

 

        #region 将此控件呈现给指定的输出参数

        /// <summary>

        /// 将此控件呈现给指定的输出参数

        /// </summary>

        /// <param name="output"> 要写出到的 HTML 编写器</param>

        protected override void Render(HtmlTextWriter output)

        {

 

            GetPandC();

 

            #region    省市连选所需的javascript函数

 

            if (!this.Page.IsClientScriptBlockRegistered("PandC_clientScript"))

            {

                output.WriteLine("<script language=\"JavaScript\">");

                output.WriteLine("var groups=" + (parr.Count + 1) + ";");

                output.WriteLine("var group=new Array(groups);");

                output.WriteLine("for (i=0; i<groups; i++)");

                output.WriteLine("group[i]=new Array();");

                //选项0对应二级下拉框

                output.WriteLine("group[0][0]=new Option(\"请选择\",\"\");");

                for (int i = 0; i < carr.Count; i++)

                {

                    ArrayList arr = (ArrayList)carr[i];

                    output.WriteLine("group[" + (i + 1) + "][0]=new Option(\"请选择\",\"" + parr[i].ToString() + "\");");

                    for (int j = 0; j < arr.Count; j++)

                    {

                        output.WriteLine("group[" + (i + 1) + "][" + (j + 1) + "]=new Option(\"" + arr[j].ToString() + "\",\"" + parr[i].ToString() + arr[j].ToString() + "\");");

                    }

                }

                output.WriteLine("function redirectff(x,obj){");

                output.WriteLine("for (m=obj.options.length-1;m>0;m--)");

                output.WriteLine("obj.options[m]=null;");

                output.WriteLine("for (i=0;i<group[x].length;i++){");

                output.WriteLine("obj.options[i]=new Option(group[x][i].text,group[x][i].value);");

                output.WriteLine("obj.options[0].selected=true;");

                output.WriteLine("}}");

                output.WriteLine("</script>");

                this.Page.RegisterClientScriptBlock("PandC_clientScript", "");

            }

 

            #endregion

 

            #region select部分

 

            //初始化

            output.Write("<select id=\"" + this.ID + "_p\" name=\"" + this.ID + "_p\" onChange=\"redirectff(this.options.selectedIndex,document.all." + this.ID + ")\" ");

            //select的其他属性(如何将WebControl的属性很方便的全部应用到控件中呢)

            if (this.CssClass != "")

            {

                output.Write(" class=\"" + this.CssClass + "\"");

            }

            output.Write(">");

            //option

           

            output.Write("<option>请选择</option>");

            //找出初始选定的省

            int pindex = 0;

            for (int i = 0; i < parr.Count; i++)

            {

                if (this.Text != null)

                {

                    //根据选定值给出默认项

                    if (this.Text.IndexOf(parr[i].ToString()) > -1)

                    {

                        output.Write("<option selected>" + parr[i].ToString() + "</option>");

                        pindex = i + 1;

                    }

                    else

                    {

                        output.Write("<option>" + parr[i].ToString() + "</option>");

                    }

                }

                else

                {

                    output.Write("<option>" + parr[i].ToString() + "</option>");

                }

 

            }

           output.Write("</select>");

            output.Write(this.One_Name); //一级名称

            output.Write("<select id=\"" + this.ID + "\" name=\"" + this.ID + "\"");

            if (this.CssClass != "")

            {

                output.Write(" class=\"" + this.CssClass + "\"");

            }

            output.Write(">");

           

            output.Write("<option value=\"\">请选择</option>");

            //根据初始化选定的省来选定市

            if (pindex > 0)

            {

                ArrayList arr = (ArrayList)carr[pindex];

                for (int i = 0; i < arr.Count; i++)

                {

                }

            }

            output.Write("</select>");

            output.Write(this.Two_Name); //二级名称

 

            #endregion

        }

 

        #endregion

 

        #region XML文件中读取一级,二级关联信息

        /// <summary>

        /// XML文件中读取一级,二级关联信息

        /// </summary>

        /// <returns></returns>

        private void GetPandC()

        {

            ArrayList arr = new ArrayList();

 

            //从资源中获取

            try

            {

                SiteXmlFileName = Context.Server.MapPath(this._sitemapxmlfile.ToString());

            }

            catch (Exception ex)

            {

                //throw new FileNotFoundException("Do not Find SiteMapXmlFile!");

            }

            try

            {

 

                XmlTextReader xr = new XmlTextReader(SiteXmlFileName);

                while (xr.Read())

                {

                    if (xr.NodeType == XmlNodeType.Element && xr.Name == "one")

                    {

                        parr.Add(xr.GetAttribute("name"));

                        arr = new ArrayList();

                    }

                    if (xr.NodeType == XmlNodeType.Element && xr.Name == "two")

                    {

                        arr.Add(xr.GetAttribute("name"));

                    }

                    if (xr.NodeType == XmlNodeType.EndElement && xr.Name == "one")

                    {

                        carr.Add(arr);

 

                    }

                }

                xr.Close();

            }

            catch (Exception ex)

            {

 

            }

        }

       

        #endregion

 

        #region IPostBackDataHandler 成员

 

        public event EventHandler TextChanged;

 

        /// <summary>

        /// 当由类实现时,用信号要求服务器控件对象通知 ASP.NET 应用程序该控件的状态已更改。

        /// </summary>

        public virtual void RaisePostDataChangedEvent()

        {

            OnTextChanged(EventArgs.Empty);

        }

 

 

        protected virtual void OnTextChanged(EventArgs e)

        {

            if (TextChanged != null)

                TextChanged(this, e);

        }

 

        /// <summary>

        /// 当由类实现时,为 ASP.NET 服务器控件处理回发数据。

        /// </summary>

        /// <param name="postDataKey">控件的主要标识符</param>

        /// <param name="postCollection">所有传入名称值的集合</param>

        /// <returns>如果服务器控件的状态在回发发生后更改,则为 true;否则为 false</returns>

        public virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)

        {

            String presentValue = Text;

            String postedValue = postCollection[postDataKey];

 

            if (presentValue == null || !presentValue.Equals(postedValue))

            {

                Text = postedValue;

                return true;

            }

 

            return false;

        }

 

        #endregion

    }

}

由于空间问题,就不在此提供下在源程序和控件的地方了,如有哪为朋友需要的话,我可以Email 给他.

   
                       

原文地址:https://www.cnblogs.com/ziyan22/p/739367.html