自带的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>
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;
}
}
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;
}
}
实例代码仅供参考。