zoukankan      html  css  js  c++  java
  • 使用Asp.net的TreeView来构建用户选择输入

    选择优于输入,这是一般人的共识,面对繁多的数据,提供良好的选择界面,一方面增强用户的界面体验,一方面也提高了数据的准确性,更节省了用户的宝贵时间。一般的单项数据选择可以使用DropdownList控件来实现,但对于有多个选择性输入,而且输入有层次关系的内容,最好选择TreeView控件来实现。

     

    本文介绍如何使用使用TreeView控件来有效获取用户的输入,其中涉及到TreeView控件的级联选择、去掉节点HTML链接变为展开目录、获取选择内容、如何构造数据库的信息变为树形内容以及弹出窗口使用等知识点,本文输入应用级别的例子,希望能做个记号,对己对人,皆为利好!^_^

    本文的经营范围是一个可以输入分类及详细子内容的,由于内容繁多,而且具有一定的层次关系,因此,不适合采用DropdownListCheckboxList控件,因此采用了带CheckBox属性的TreeView控件来辅助用户的输入。

    输入界面大致如下所示,用户通过选择按钮,触发弹出对话框,在对话框中放置了TreeView控件。

     

    在弹出的对话框中,放置的TreeView控件,一个带有CheckBox,可以方便用户选择,并且具有级联(通过Javascript实现,减少Post回发),另外由于内容比较多,我设置了展开的级别层次。

    用户通过选择或者反选大类,可以选择或反选其列表下面的所有项目,也可以单独选择子项目。

     

    由于通过Javascript不太好获取并组装返回的内容,本文通过了在后台遍历树的方式对返回值进行处理,然后在父窗体的Javascript中对返回值进行了绑定,使其在界面控件中得以显示指定格式的内容。

     

     

    以下为HTML的代码,其中OnTreeNodeChecked为级联Javascript函数,SubmitValue为对返回值进行绑定的操作。

      代码

        <div class="search">
            
    <span>
                
    <asp:ImageButton ID="btnSelect" runat="server" 
                ImageUrl
    ="~/Themes/Default/btn_select.gif" onclick="btnSelect_Click"
                    
    />
                
    <asp:ImageButton ID="btnClose" runat="server" OnClientClick="javascript:window.close();return false;"
                    ImageUrl
    ="~/Themes/Default/btn_close.gif" />
            
    </span>
            
    <table cellspacing="0" cellpadding="0" border="0" width="100%">
                
    <tr>
                    
    <td class="ico">
                        
    &nbsp;
                    
    </td>
                    
    <td class="form">
                        
    <asp:TreeView ID="TreeView1" runat="server" onclick="OnTreeNodeChecked();" ShowCheckBoxes="All"
                            ShowLines
    ="True" ExpandDepth="1" Font-Bold="False" ForeColor="#0000CC">
                        
    </asp:TreeView>
                    
    </td>
                
    </tr>
            
    </table>
        
    </div>

        
    <script language='javascript' type='text/javascript'>
            
    function OnTreeNodeChecked() {
                
    var ele = event.srcElement;
                
    if (ele.type == 'checkbox') {
                    
    var childrenDivID = ele.id.replace('CheckBox', 'Nodes');
                    
    var div = document.getElementById(childrenDivID);
                    
    if (div == nullreturn;
                    
    var checkBoxs = div.getElementsByTagName('INPUT');
                    
    for (var i = 0; i < checkBoxs.length; i++) {
                        
    if (checkBoxs[i].type == 'checkbox')
                            checkBoxs[i].checked = ele.checked;
                    }
                }
            }

            
    function SubmitValue() {
                
    var val = "";
                
    var returnVal = new Array();
                
    var inputs = document.all.tags("INPUT");
                
    var n = 0;
                
    for (var i = 0; i < inputs.length; i++) // 
    遍历页面上所有的 input 
                {
                    
    if (inputs[i].type == "checkbox") {
                        
    if (inputs[i].checked) {
                            
    var strValue = inputs[i].value;
                            val += strValue + ',';
                            
    //returnVal[n] = val;
                            n = n + 1;
                        }
                    } 
    //if(inputs[i].type="checkbox")
                } //for
                
                window.returnValue = val;
                window.close();
            }
            
        
    </script>

     

     下面代码是页面的后台代码,其中展示了如何对树进行数据绑定,使其能够显示有层次格式的内容,其中AddTreeNode是一个递归函数。btnSelect_Click事件处理函数,专门对返回的数据进行组装,以一定的格式显示到客户端的控件输入上。

      代码

            protected void Page_Load(object sender, EventArgs e)
            {
                
    if (!this.IsPostBack)
                {
                    BindData();
                }
            }

            
    private void BindData()
            {
                ArrayList scopeTree = BLLFactory<BusinessScope>.Instance.GetTree();
                
    foreach (BusinessScopeNodeInfo nodeInfo in scopeTree)
                {
                    TreeNode node = 
    new TreeNode(nodeInfo.Name);
                    node.SelectAction = TreeNodeSelectAction.Expand;
                    
    this.TreeView1.Nodes.Add(node);

                    AddTreeNode(node, nodeInfo);
                }
            }

            
    private void AddTreeNode(TreeNode parentNode, BusinessScopeNodeInfo nodeInfo)
            {
                TreeNode treeNode = 
    null;
                
    foreach (BusinessScopeNodeInfo subNodeInfo in nodeInfo.Children)
                {
                    treeNode = 
    new TreeNode(subNodeInfo.Name);
                    treeNode.SelectAction = TreeNodeSelectAction.Expand;
                    parentNode.ChildNodes.Add(treeNode);

                    AddTreeNode(treeNode, subNodeInfo);
                }
            }

            
    protected void btnSelect_Click(object sender, ImageClickEventArgs e)
            {
                
    string result = "";
                
    foreach (TreeNode parent in this.TreeView1.Nodes)
                {
                    
    foreach (TreeNode node in parent.ChildNodes)
                    {
                        StringBuilder sb = 
    new StringBuilder();
                        
    foreach (TreeNode subNode in node.ChildNodes)
                        {
                            
    if (subNode.Checked)
                            {
                                sb.AppendFormat(
    "{0},", subNode.Text);
                            }
                        }
                        
    if (sb.Length > 0)
                        {
                            sb.Insert(
    0string.Format("{0}(", node.Text));
                            sb.Append(
    ")");
                            result += sb.ToString().Replace(
    ",)"")") + ";";
                        }
                        
    else if (node.Checked)
                        {
                            result += node.Text;
                        }                    
                    }
                }
                Helper.CloseWin(
    this, result.Trim(';'));
            }

     

     其中数的数据组装也是需要注意的一个地方,为了提高效率,避免频繁查找数据库,我们先把符合条件的数据放到DataTable,然后通过对象的Select在内存中查找,这样可以很好的提高递归函数的查找效率。

      代码

            /// <summary>
            
    /// 
    获取数据树
            
    /// </summary>
            
    /// <returns></returns>
            public ArrayList GetTree()
            {
                ArrayList arrReturn = 
    new ArrayList();
                
    string sql = string.Format("Select * From {0} Order By PID, Seq ", tableName);
                Database db = DatabaseFactory.CreateDatabase();
                DbCommand cmdWrapper = db.GetSqlStringCommand(sql);

                DataSet ds = db.ExecuteDataSet(cmdWrapper);
                
    if (ds.Tables.Count > 0)
                {
                    DataTable dt = ds.Tables[
    0];
                    DataRow[] dataRows = dt.Select(
    string.Format(" PID = {0}", -1));
                    
    for (int i = 0; i < dataRows.Length; i++)
                    {
                        
    int id = Convert.ToInt32(dataRows[i]["ID"]);
                        BusinessScopeNodeInfo menuNodeInfo = GetNode(id, dt);
                        arrReturn.Add(menuNodeInfo);
                    }
                }

                
    return arrReturn;
            }


            
    private BusinessScopeNodeInfo GetNode(int id, DataTable dt)
            {
                BusinessScopeInfo menuInfo = 
    this.FindByID(id);
                BusinessScopeNodeInfo menuNodeInfo = 
    new BusinessScopeNodeInfo(menuInfo);

                DataRow[] dChildRows = dt.Select(
    string.Format(" PID={0}", id));

                
    for (int i = 0; i < dChildRows.Length; i++)
                {
                    
    int childId = Convert.ToInt32(dChildRows[i]["ID"]);
                    BusinessScopeNodeInfo childNodeInfo = GetNode(childId, dt);
                    menuNodeInfo.Children.Add(childNodeInfo);
                }
                
    return menuNodeInfo;
            }

     

     其中所用到的数据实体如下面两个类所示,其中BusinessScopeNodeInfo 是对象 BusinessScopeInfo的进一步封装,方便提供树的基本信息,也就是BusinessScopeNodeInfo 是一个包含了子类数据的对象,BusinessScopeInfo仅仅是数据库对象的映射实体。

    代码

        /// <summary>
        
    /// BusinessScopeNodeInfo 
    的摘要说明。
        
    /// </summary>
        public class BusinessScopeNodeInfo : BusinessScopeInfo
        {
            
    private ArrayList m_Children = new ArrayList();

            
    /// <summary>
            
    /// 子菜单实体类对象集合
            
    /// </summary>
            public ArrayList Children
            {
                
    get { return m_Children; }
                
    set { m_Children = value; }
            }

            
    public BusinessScopeNodeInfo()
            {
                
    this.m_Children = new ArrayList();
            }

            
    public BusinessScopeNodeInfo(BusinessScopeInfo scopeInfo)
            {
                
    base.Id = scopeInfo.Id;
                
    base.Name = scopeInfo.Name;
                
    base.Seq = scopeInfo.Seq;
            }
        }

     

      代码

        [Serializable]
        
    public class BusinessScopeInfo : BaseEntity
        {    
            
    #region Field Members

            
    private decimal m_Id = 0;         
            
    private decimal m_Pid = -1;         
            
    private string m_Name = "";         
            
    private string m_Seq = "";         

            
    #endregion

            
    #region Property Members
            
            
    public virtual decimal Id
            {
                
    get
                {
                    
    return this.m_Id;
                }
                
    set
                {
                    
    this.m_Id = value;
                }
            }

            
    public virtual decimal Pid
            {
                
    get
                {
                    
    return this.m_Pid;
                }
                
    set
                {
                    
    this.m_Pid = value;
                }
            }

            
    public virtual string Name
            {
                
    get
                {
                    
    return this.m_Name;
                }
                
    set
                {
                    
    this.m_Name = value;
                }
            }

            
    public virtual string Seq
            {
                
    get
                {
                    
    return this.m_Seq;
                }
                
    set
                {
                    
    this.m_Seq = value;
                }
            }


            
    #endregion

        }

     

    其中的数据格式大致如下(本文的例子是在Oracle环境中工作的),其实SqlServer或者其他数据库也是一样。

     

    主要研究技术:代码生成工具、会员管理系统、客户关系管理软件、病人资料管理软件、Visio二次开发、酒店管理系统、仓库管理系统等共享软件开发
    专注于Winform开发框架/混合式开发框架Web开发框架Bootstrap开发框架微信门户开发框架的研究及应用
      转载请注明出处:
    撰写人:伍华聪  http://www.iqidi.com 
        
  • 相关阅读:
    Power BI for Office 365(八)共享查询
    Power BI for Office 365(七) Power BI站点
    Power BI for Office 365(六)Power Map简介
    Power BI for Office 365(五)Power View第二部分
    Power BI for Office 365(四)Power View第一部分
    Power BI for Office 365(三)Power Pivot
    Power BI for Office 365(二)Power Query
    java 继承、重载、重写与多态
    Android 热修复方案Tinker(一) Application改造
    阿里最新热修复Sophix与QQ超级补丁和Tinker的实现与总结
  • 原文地址:https://www.cnblogs.com/wuhuacong/p/1633572.html
Copyright © 2011-2022 走看看