GridView多级复选框级联选中

在项目开发中,一般情况下都使用TreeView控件,实现级联选中效果更简单方便,但是为了显示内容更加直观而尝试了使用gridview来实现。


1、首先实现合并相同行,方法代码如下。

///<summary>

    ///合并行

    ///</summary>

    ///<paramname="gvw">需要合并的GridView</param>

    ///<paramname="sCol">要合并开始列</param>

    ///<paramname="eCol">要合并的结束列</param>

    public static voidMergeRows(GridView gvw,int sCol,int eCol)//gvw需要合并的GridView,sCol要合并开始列(从0开始),eCol要合并的结束列 

    {

        //如果第3列相同,则第1、2、3列合并单元格,如果第1列,则第0、1合并单元格

        for (int rowIndex = gvw.Rows.Count - 2; rowIndex >= 0;rowIndex--)

        {

            GridViewRowrow = gvw.Rows[rowIndex];

            GridViewRowpreviousRow = gvw.Rows[rowIndex + 1];

            for(int i = sCol; i < eCol + 1; i++)

            {

                if(row.Cells[i].Text !=""&& row.Cells[i].Text !=" ")

                {

                    if(row.Cells[i].Text == previousRow.Cells[i].Text)

                    {

                        row.Cells[i].RowSpan =previousRow.Cells[i].RowSpan < 1 ? 2 : previousRow.Cells[i].RowSpan + 1;

                       previousRow.Cells[i].Visible = false;

                        row.Cells[i -1].RowSpan = previousRow.Cells[i - 1].RowSpan < 1 ? 2 : previousRow.Cells[i- 1].RowSpan + 1;

                        previousRow.Cells[i -1].Visible = false;

                        for (int j = row.RowIndex +row.Cells[i].RowSpan - 1; j >= row.RowIndex; j--)

                        {

                            CheckBox cbx1 =newCheckBox();

                            CheckBox cbx2 =newCheckBox();

                            CheckBox cbx3 =newCheckBox();

                            if (i == 1)

                            {

                                cbx2 =gvw.Rows[j].Cells[i + 1].FindControl("cb_Check2")asCheckBox;

                                cbx1 =row.Cells[i - 1].FindControl("cb_Check1")asCheckBox;

                               cbx2.Attributes.Remove("parentId");

                               cbx2.Attributes.Add("parentId",cbx1.ClientID);

                            }

                            else

                            {

                                cbx3 =gvw.Rows[j].Cells[i + 1].FindControl("cb_Check3")asCheckBox;

                                cbx2 =row.Cells[i - 1].FindControl("cb_Check2")asCheckBox;

                                cbx3.ToolTip =cbx2.ClientID;

                               cbx3.Attributes.Remove("parentId");

                               cbx3.Attributes.Add("parentId",cbx2.ClientID);

                            }

 

                        }

                    }

                }

            }

        }

}

2、为gridview中的复选框添加js事件,并初始化parentId属性(我自己命名的属性,存储父级复选框的id值,而这样赋值的结果是给复选框加了一个span标签:

<spantitle="GridView1_ctl02_cb_Check2"parentId="GridView1_ctl02_cb_Check2"><inputid="GridView1_ctl02_cb_Check3"type="checkbox"name="GridView1$ctl02$cb_Check3"onclick="selectIndex('GridView1','GridView1_ctl02_cb_Check3');"/></span>

代码如下:

  protected void GridView1_RowDataBound(objectsender, GridViewRowEventArgs e)

    {

        //禁用复选框(已经下载或已经上传的项目不能再下载)

        if(e.Row.RowType == DataControlRowType.DataRow)

        {

            CheckBoxcbx1 = e.Row.FindControl("cb_Check1")asCheckBox;

            CheckBoxcbx2 = e.Row.FindControl("cb_Check2")asCheckBox;

            CheckBoxcbx3 = e.Row.FindControl("cb_Check3")asCheckBox;

            stringstate = e.Row.Cells[7].Text.Trim();

            if(state == "已下载"|| state == "已上传")

                cbx3.Enabled = false;

            else

                cbx3.Enabled = true;

            //根据子节点的enable属性设置父节点的enable

            ScriptManager.RegisterStartupScript(Page,GetType(),"","SetDisabled('" + GridView1.ClientID +"','3');",true);

            //给复选框添加js事件

            cbx1.Attributes.Add("onclick","selectIndex('"+ GridView1.ClientID +"','" +cbx1.ClientID +"')");

            cbx2.Attributes.Add("onclick","selectIndex('"+ GridView1.ClientID +"','" +cbx2.ClientID +"')");

            cbx3.Attributes.Add("onclick","selectIndex('"+ GridView1.ClientID +"','" +cbx3.ClientID +"')");

            cbx2.Attributes.Add("parentId", cbx1.ClientID);

            cbx3.Attributes.Add("parentId", cbx2.ClientID); ;

        }

   }

3、 Js方法1:unChecked(GVID,CBXID),参数分别代表:gridview的id及复选框id。反选该复选框时,则其父级复选框也应反选。代码如下:

function unChecked(GVID, CBXID) {

            /*

            如果是反选,则将父项也反选;

            */

            checkbox2 =document.getElementById(CBXID);

            if(!checkbox2.checked) {

                try{

                    varparent = document.getElementById(checkbox2.parentNode.attributes("parentId").value);

                    parent.checked = false;

                    unChecked(GVID,checkbox2.parentNode.attributes("parentId").value);

                }

                catch(Error) { }

            }

        }

4、 Js方法2:DoChecked(GVID,CBXID),参数分别代表:gridview的id及复选框id。选中该复选框时,如果该级复选框全部选中,则其父级复选框也应选中。代码如下:

functionDoChecked(GVID, CBXID) {

            /*  如果是选中,则判断父项的所有enable=true的子项是否全部选中,如果是,则选中父项  */

            checkbox2 =document.getElementById(CBXID);

            if(checkbox2.checked) {

                chsParent =document.getElementById(GVID).getElementsByTagName("INPUT");

                j = 0;

                varflag = true;

                for(j = 0; j < chsParent.length; j++) {

                    if(!chsParent[j].disabled) {

                       try {

                            var parentId = chsParent[j].parentNode.attributes("parentId").value;

                            if (parentId == checkbox2.parentNode.attributes("parentId").value &&!chsParent[j].checked) {

                                flag = false;

                            }

                        } catch (Error) { }

                    }

                }

                if(flag) {

                    try{

                        var parent = document.getElementById(checkbox2.parentNode.attributes("parentId").value);

                        parent.checked = true;

                        DoChecked(GVID,checkbox2.parentNode.attributes("parentId").value);

                    }

                    catch(Error) { }

                }

            }

       }

5、 Js事件1:selectIndex(GVID,CBXID, TYPE),参数分别代表:gridview的id、复选框id及类型。通过递归实现选中该复选框,则其所有子级复选框选中,反选该复选框,则其所有子级复选框反选;同时对触发事件的复选框,执行js方法1及方法2。使用type参数就是为了区别传入的CBXID参数是触发事件的复选框,还是递归时的子级复选框,当type== undefined时,为触发事件的复选框。具体代码如下:

functionselectIndex(GVID, CBXID, TYPE) {

            varcheckbox1 = document.getElementById(CBXID);

            if(document.getElementById(GVID) !=null) {

                chs =document.getElementById(GVID).getElementsByTagName("INPUT");

                n = 0;

                for(i = 0; i < chs.length; i++) {

                    if(!chs[i].disabled) {

                        /*

                        把子项的选中状态与本项状态一致

                        */

                        try {

                            var parentId = chs[i].parentNode.attributes("parentId").value;

                            if (parentId == CBXID) {

                                chs[i].checked= document.getElementById(CBXID).checked;//递归后checkbox1发生变化,所以不能直接用checkbox1

                                var m = i;

                                TYPE = 1;

                               selectIndex(GVID, chs[i].attributes("id").value,1);

                                TYPE =undefined;

                                i = m;

                            }

                        } catch (Error) { }

                    }

                }

            }

            if(TYPE == undefined) {

                unChecked(GVID, CBXID);

                DoChecked(GVID, CBXID);

            }

       }

6、 Js方法3:SetDisabled(GVID,index)参数分别代表:gridview的id,gridview中复选框的最子级别的索引,级别从1开始,本文的例子最子级别的索引为3。(如果实现此方法,则复选框的命名规则必须为:" cb_Check"+ index)此方法是为了初始化gridview中的复选框的disabled属性值:如果子节点复选框disabled全为true,则父节点也不可用,否则父节点可用。在绑定完gridview时,调用此方法。具体代码如下:

functionSetDisabled(GVID, index) {

            /*

            index为checkbox最子级别,并且最父级从1开始

            如果子节点复选框disabled全为true,则父节点也不可用,否则父节点可用

            */

            varstrCBXID = "Check" + index; //复选框的id后缀名

            vararr = new Array();

            varparentId;

            chsChild =document.getElementById(GVID).getElementsByTagName("INPUT");

            j = 0;

            //只循环最后一列checkbox,然后再通过递归

            for(j = 0; j < chsChild.length; j++) {

                if(chsChild[j].disabled && chsChild[j].attributes("id").value.indexOf(strCBXID)) {

                    try{

                        parentId =chsChild[j].parentNode.attributes("parentId").value;

                        var isHave =false;

                        for (var m = 0; m < arr.length;m++) {

                            if (parentId == arr[m]) {

                                isHave = true;

                                break;

                           }

                        }

                        if (isHave)

                            continue;

                        else {

                            var flag =true;

                            chsBrother =document.getElementById(GVID).getElementsByTagName("INPUT");

                            for (u = 0; u < chsBrother.length; u++) {

                                try {

                                    if (parentId == chsBrother[u].parentNode.attributes("parentId").value &&!chsBrother[u].disabled) {

                                        flag = false;

                                    }

                                } catch (Error) { }

                            }

                            if (flag) {

                                varobjParent = document.getElementById(parentId);

                               objParent.disabled = true;

                            }

                            if (parentId != undefined && parentId !='')

                                arr.push(parentId);

                        }

                    } catch(Error) {

 

                    }

                }

            }

            if(index > 1)

                SetDisabled(GVID, index - 1);

       }

结语:在开发过程中,经常会遇到在网上找不到解决方案的新问题,那就需要一种勇于尝试和挑战的心态。在尝试的过程中,也要考虑代码复用性,以便可以解决这一类问题。当然我写的肯定不是最好最简洁的代码,也希望各位领导及同事能给予更多的建议和意见。


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值