做的项目,需要用到TreeView来处理一些分级数据,并能允许同时选中多个节点(要求选中父节点,那么子节点也相应的选中),即要用TreeView的ShowCheckBox属性。但在使用时发现,在选中复选框时不会引起回发事件,于是一顿猛Google。看到使用__doPostBack和后台注册onclick事件可以解决此问题,用上后却一直报__doPostBack()‘缺少对象’错误,在网上又搜到“NET 生成javascript的 __doPostBack()函数是有条件的,当页面上存在一个或一个以上的LINKBUTTON的时候才会有这个函数,所以,如果页面上没有LINKBUTTON只有BUTTON的时候会出现‘缺少对象’的JS错误提示”,于是马上在页面放一用样式隐藏的LINKBUTTON,可问题依旧。这可怎办?因此还一度以为我把__doPostBack()的单词写错了,反反复复的进行单词对照,竟让我发现我的_doPostBack()的‘_’要比网上的‘__’短,修正过后,一切正常,终于OK。
经调试,不用LINKBUTTON亦可。
贴上相关源码
.aspx文件中加一段JavaScript:
<script type="text/javascript">
// 点击复选框时触发事件
function postBackByObject()
{
var o = window.event.srcElement;
if (o.tagName == "INPUT" && o.type == "checkbox")
{
//这里的第一个参数是UpdatePanel ID,因为我使用了MS的ASPAJAX来实现局部刷新
//如果没有使用MS的ASPAJAX,这里的两个参数都可以为空
__doPostBack("UP_TreeView","");
}
}
</script>
.cs文件
protected void BindTreeViewData()
{
//
//省略TreeView的数据绑定
//
TreeView1.Attributes.Add("onclick", "postBackByObject()");
}
#region 级联父子节点的复选框状态
protected void TreeView1_TreeNodeCheckChanged(object sender, TreeNodeEventArgs e)
{
SetChildChecked(e.Node);
// 判断是否是根节点
if (e.Node.Parent != Null)
{
SetParentChecked(e.Node);
}
}
/// <summary>
/// 根据父节点状态设置子节点的状态
/// </summary>
/// <param name="parentNode"></param>
private void SetChildChecked(TreeNode parentNode)
{
foreach (TreeNode node in parentNode.ChildNodes)
{
node.Checked = parentNode.Checked;
if (node.ChildNodes.Count > 0)
{
SetChildChecked(node);
}
}
}
/// <summary>
/// 根据子节点状态设置父节点的状态
/// </summary>
/// <param name="childNode"></param>
private void SetParentChecked(TreeNode childNode)
{
TreeNode parentNode = childNode.Parent;
if (!parentNode.Checked && childNode.Checked)
{
int ichecks = 0;
foreach (TreeNode node in parentNode.ChildNodes)
{
if (node.Checked)
{
ichecks++;
}
}
if (ichecks == parentNode.ChildNodes.Count)
{
parentNode.Checked = true;
if (parentNodeParent != Null)
{
SetParentChecked(parentNode);
}
}
}
else if (parentNode.Checked && !childNode.Checked)
{
parentNode.Checked = false;
}
}
#endregion