星期零

技术改变生活,分享让我们快乐!
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

自带的treeview,在使用checkbox时,当选中某节点时,其子节点全部选中,父节点也相应选中,这种联动方式在vs2003时,很容易实现,以后版本的treeview已经没有了autopostback,这变成了个难题,找了很久终于找到一个实现的方式,而且还解决了不同浏览器的兼容问题。实例如下:

 

 

 

treeviewcheckbox.aspx代码:

 

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="treeviewcheckbox.aspx.cs"
    Inherits
="treeviewcheckbox" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script type="text/javascript" language="javascript">
        
function postBackByObject(event) {
            
var o = (window.event) ? window.event.srcElement : event.target;
            
if (o.nodeName == "INPUT" && o.type == "checkbox") {
                __doPostBack(
"""");
            }
        }
    
</script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <table width="700" border="0" cellspacing="0" cellpadding="0">
            <tr>
                <td width="300" valign="top" style="text-align: left">
                    <br />
                    <asp:TreeView ID="TreeView1" runat="server" ShowLines="True" OnTreeNodeCheckChanged="TreeView1_TreeNodeCheckChanged"
                        ShowCheckBoxes
="All">
                    </asp:TreeView>
                </td>
                <td valign="top">
                    <asp:Button ID="Button1" runat="server" Text="获得值" OnClick="Button1_Click" />
                    <asp:Label ID="Label1" runat="server" Text=""></asp:Label>
                </td>
            </tr>
        </table>
    </div>
    </form>
</body>
</html>

 

treeviewcheckbox.aspx.cs代码:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class treeviewcheckbox : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        TreeView1.EnableClientScript = true;
        TreeView1.Attributes.Add("onclick""postBackByObject(event)");


        if (!Page.IsPostBack)
        {
            treeBind();
        }
    }


    public void treeBind()
    {

        TreeNode firstNode = new TreeNode();
        firstNode.Text = "根节点";
        firstNode.Value = "0";
        TreeView1.Nodes.Add(firstNode);

        for (int i = 1; i < 3; i++)
        {
            TreeNode tempNode = new TreeNode();

            tempNode.Text = "节点" + i.ToString();
            tempNode.Value = i.ToString();

            firstNode.ChildNodes.Add(tempNode);


            for (int j = 1; j < 3; j++)
            {
                TreeNode tempNode1 = new TreeNode();

                tempNode1.Text = "节点" + i.ToString() + "" + j.ToString();
                tempNode1.Value = i.ToString() + "" + j.ToString();

                tempNode.ChildNodes.Add(tempNode1);


                for (int n = 1; n < 3; n++)
                {
                    TreeNode tempNode11 = new TreeNode();

                    tempNode11.Text = "节点" + i.ToString() + "" + j.ToString() + "" + n.ToString();
                    tempNode11.Value = i.ToString() + "" + j.ToString() + "" + n.ToString();

                    tempNode1.ChildNodes.Add(tempNode11);
                }
            }


        }

    }

    protected void TreeView1_TreeNodeCheckChanged(object sender, TreeNodeEventArgs e)
    {
        //Recursive change its children's checked states.
        RecursiveCheckCheckBox(e.Node, e.Node.Checked, true);
        //If current node is unchecked then check whether all its sibling are
        
// unchecked, if so, unchecked its parent node.
        TreeNode current = e.Node;
        while (!current.Checked && current.Parent != null && !IsChildNodesChecked(current.Parent))
        {
            current.Parent.Checked = false;
            current = current.Parent;
        }
        //If current node is checked then recursive checked its ancestor nodes.
        if (e.Node.Checked)
        {
            RecursiveCheckCheckBox(e.Node, e.Node.Checked, false);
        }


    }

    /// <summary>
    
/// Check a node's direct children is checked.
    
/// This function needn't be a recursive one, because I find that I only
    
/// need to check its direct children's state, it will be much faster
    
/// than use recursive.
    
/// </summary>
    
/// <param name="n">a given node</param>
    
/// <returns>true if its direct children is checked, false otherwise</returns>
    private bool IsChildNodesChecked(TreeNode n)
    {
        bool result = false;
        if (n.ChildNodes.Count == 0)
        {
            result = n.Checked;
        }
        foreach (TreeNode t in n.ChildNodes)
        {
            if (result |= t.Checked)
            {
                break;
            }
        }
        return result;
    }
    /// <summary>
    
/// Recursive set a node's child nodes' checked states to it's parent's.
    
/// </summary>
    
/// <param name="n">a given node</param>
    
/// <param name="isChecked">whether nodes are checked</param>
    
/// <param name="topDown">whether to go topdown or downtop</param>
    private void RecursiveCheckCheckBox(TreeNode n, bool isChecked, bool topDown)
    {
        if (topDown)
        {
            foreach (TreeNode l in n.ChildNodes)
            {
                l.Checked = isChecked;
                if (l.ChildNodes.Count != 0)
                {
                    RecursiveCheckCheckBox(l, isChecked, topDown);
                }
            }
        }
        else
        {
            n.Checked = isChecked;
            if (n.Parent != null)
            {
                RecursiveCheckCheckBox(n.Parent, isChecked, false);
            }
        }
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        string powerstr = "#";

        powerstr = powerstr + getCheckedNodeValue(TreeView1.Nodes);

        Label1.Text = powerstr;
    }

    public string getCheckedNodeValue(TreeNodeCollection aNodes)
    {
        string powerstr = "";

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

            if (aNodes[i].Checked == true)
            {
                powerstr = powerstr + aNodes[i].Value + "#";
            }

            if (aNodes[i].ChildNodes.Count > 0)
            {
                powerstr = powerstr + getCheckedNodeValue(aNodes[i].ChildNodes);
            }
        }

        return powerstr;
    }



}

实例代码仅供参考。