正版软件交易论坛

首页 » 技术咨询区 » 综合其他(没有开版的技术在此讨论) » 扩展TreeView控件(1) - 联动复选框(复选框的全选和取消全选)
snail - 2007-8-20 14:08:00
TreeView既强大又好用。为了让它更强大、更好用,我们来写一个继承自TreeView的控件。

扩展TreeView控件(1) - 联动复选框(复选框的全选和取消全选)


作者:webabcd


介绍
扩展TreeView控件:
联动复选框(复选框的全选和取消全选)。选中指定的父复选框,则设置其所有子复选框为选中状态;取消选中指定的父复选框,则设置其所有子复选框为取消选中状态。如果某父复选框的所有子复选框为均选中状态,则设置该父复选框为选中状态;如果某复选框的所有子复选框至少有一个为取消选中状态,则设置该父复选框为取消选中状态

使用方法(设置属性):
AllowCascadeCheckbox - 是否启用联动复选框功能


关键代码
相关的js
//----------------------------
//
http://webabcd.cnblogs.com/
//
----------------------------

/**//*Helper 开始*/
String.prototype.yy_stv_startsWith
=
function(s)

/// <summary>StartsWith()</summary>

   
var reg =
new RegExp("^"
+ s); 
   
return reg.test(this);
}


function yy_stv_addEvent(obj, evtType, fn)
{
/// <summary>绑定事件</summary>

   
// FF

if (obj.addEventListener)
   
{
        obj.addEventListener(evtType, fn,
true);
       
return
true;
    }

   
// IE

else
if (obj.attachEvent)
   
{
       
var r = obj.attachEvent("on"
+ evtType, fn);
       
return r;
    }

   
else
   
{
       
return
false;
    }
   
}

/**//*Helper 结束*/


/**//*联动复选框 开始*/
var yy_stv_ccTreeView_pre =
new Array(); // cs中动态向其灌数据(TreeView内控件ID的前缀数组)

function yy_stv_ccClickCheckbox(e)
{
/// <summary>单击复选框时</summary>

   
var evt = e || window.event; // FF || IE

var obj = evt.target || evt.srcElement  // FF || IE
   
    yy_stv_foreachChildCheckbox(obj);
    yy_stv_foreachParentCheckbox(obj);
}



function yy_stv_checkParentCheckbox(table, checked)
{
/// <summary>设置父复选框的状态</summary>

   
var nodes = table.parentNode.parentNode.childNodes;
       
   
for (var i=1; i<nodes.length; i++)
   
{
       
if (nodes == table.parentNode)
       
{
           
if (typeof(nodes[i-1]) == 'undefined' ||
typeof(nodes[i-1].rows) == 'undefined') return;

           
for (var j=0; j < nodes[i-1].rows[0].cells.length; j++)
           
{
               
var chk = nodes[i-1].rows[0].cells[j].childNodes[0];
               
if (chk.tagName ==
"INPUT"
&& chk.type ==
"checkbox")
               
{
                    chk.checked
= checked;
                    yy_stv_foreachParentCheckbox(nodes[i
-1]);
                   
return;
                }

            }

        }

    }

}


function yy_stv_foreachChildCheckbox(obj)

/// <summary>单击父复选框时,设置其子复选框的选中状态</summary>

   
var checked;
   
   
if (obj.tagName ==
"INPUT"
&& obj.type ==
"checkbox")
   
{
        checked
= obj.checked;
       
do
       
{
            obj
= obj.parentNode;
        }

       
while (obj.tagName !=
"TABLE")
    }

   
   
var nodes = obj.parentNode.childNodes;
       
   
for (var i=0; i<nodes.length -
1; i++)
   
{
       
if (nodes == obj && nodes[i +
1].tagName ==
"DIV")
       
{
           
var elements = nodes[i+1].getElementsByTagName("INPUT");
           
           
for (j=0; j< elements.length; j++)
           
{     
               
if (elements[j].type == 'checkbox')
               
{
                    elements[j].checked
= checked;
                }

            }
   
        }

    }

}


function yy_stv_foreachParentCheckbox(obj)
{   
/// <summary>单击某一复选框时,设置其父复选框的选中状态</summary>

   
var checkedNum =
0;
   
var uncheckedNum =
0;
   
   
if (obj.tagName ==
"INPUT"
&& obj.type ==
"checkbox")
   
{
       
do
       
{
            obj
= obj.parentNode;
        }

       
while (obj.tagName !=
"TABLE")
    }

               
   
var tables = obj.parentNode.getElementsByTagName("TABLE");
   
   
if (typeof(tables) == 'undefined') return;
     
   
for (var i=0; i < tables.length; i++)
   
{       
       
for (var j=0; j < tables.rows[0].cells.length; j++)
       
{
           
var chk = tables.rows[0].cells[j].childNodes[0];
           
if (chk.tagName ==
"INPUT"
&& chk.type ==
"checkbox")
           
{
               
if (chk.checked)
                    checkedNum
++;
               
else
                    uncheckedNum
++;
            }

        }

    }

   
   
if (uncheckedNum ==
0)
   
{
        yy_stv_checkParentCheckbox(obj,
true);
    }

   
else
   
{
        yy_stv_checkParentCheckbox(obj,
false);
    }

}



function yy_stv_attachCheckboxClickListener()
{
/// <summary>监听所有联动复选框的单击事件</summary>

   
var elements =  document.getElementsByTagName("INPUT");
   
   
for (i=0; i< elements.length; i++)
   
{     
       
if (elements.type == 'checkbox')
       
{
           
for (j=0; j<yy_stv_ccTreeView_pre.length; j++)
           
{
               
if (elements.id.yy_stv_startsWith(yy_stv_ccTreeView_pre[j]))
               
{
                    yy_stv_addEvent(elements, 'click', yy_stv_ccClickCheckbox);
                   
break;
                }

            }

        }

    }
   
}


if (document.all)
{
    window.attachEvent('onload', yy_stv_attachCheckboxClickListener);
}

else
{
    window.addEventListener('load', yy_stv_attachCheckboxClickListener,
false);
}

/**//*联动复选框 结束*/


说明:
1、页面加载时为指定的TreeView的所有复选框绑定单击事件(根据复选框的前缀判断其是否属于指定的复选框)
2、单击某复选框,则遍历其所有子复选框,并进行相应的操作。同时,遍历同级复选框,并对它们的父复选框进行操作,然后再遍历它们的父复选框的同级的复选框,以此类推往上走。

相关的属性
using System;
using System.Collections.Generic;
using System.Text;

using System.ComponentModel;
using System.Web.UI;

namespace YYControls
{
   
/**////
<summary>
   
/// SmartTreeView类的属性部分
   
///
</summary>

public partial class SmartTreeView
   
{
       
private
bool _allowCascadeCheckbox;
       
/**////
<summary>
       
/// 是否启用联动复选框功能
       
///
</summary>
        [
        Browsable(
true),
        Description(
"是否启用联动复选框功能"),
        Category(
"扩展"),
        DefaultValue(
false)
        ]
       
public
virtual
bool AllowCascadeCheckbox
       
{
           
get
{ return _allowCascadeCheckbox; }
           
set
{ _allowCascadeCheckbox = value; }
        }


    }

}



相关的cs
using System;
using System.Collections.Generic;
using System.Text;

using System.Web.UI.WebControls;
using System.Web.UI;

namespace YYControls.SmartTreeViewFunction
{
   
/**////
<summary>
   
/// 扩展功能:联动复选框
   
///
</summary>

public
class CascadeCheckboxFunction : ExtendFunction
   
{
       
/**////
<summary>
       
/// 构造函数
       
///
</summary>

public CascadeCheckboxFunction()
            :
base()
       
{

        }


       
/**////
<summary>
       
/// 构造函数
       
///
</summary>
       
///
<param name="stv">SmartTreeView对象</param>

public CascadeCheckboxFunction(SmartTreeView stv)
            :
base(stv)
       
{

        }


       
/**////
<summary>
       
/// 扩展功能的实现
       
///
</summary>

protected
override
void Execute()
       
{
           
this._stv.PreRender +=
new EventHandler(_stv_PreRender);
        }


       
/**////
<summary>
       
/// SmartTreeView的PreRender事件
       
///
</summary>
       
///
<param name="sender"></param>
       
///
<param name="e"></param>

void _stv_PreRender(object sender, EventArgs e)
       
{
           
// 注册向数组中添加成员的脚本

if (!this._stv.Page.ClientScript.IsClientScriptBlockRegistered(String.Format("yy_stv_cascadeCheckbox_{0}", this._stv.ID)))
           
{
               
this._stv.Page.ClientScript.RegisterClientScriptBlock
                (
                   
this.GetType(),
                    String.Format(
"yy_stv_cascadeCheckbox_{0}", this._stv.ID),
                    String.Format(
"yy_stv_ccTreeView_pre.push('{0}');", Helper.Common.GetChildControlPrefix(this._stv)),
                   
true
                );
            }

        }

    }

}




来自博额客网

附件: yycontrols.rar
1