GridView与CheckBox的结合

GridView与CheckBox的结合,用百度或Google一搜就有一堆的出来了。但是貌似没有比较齐全的,结合自己在项目中的一个运用,我把几种实现方法都把它罗列出来,与大家一起学习。

此Example在VS2005下运行通过.

Demo如图所示:




与CheckBox结合使用的无非就是:全选,全部取消,删除所选,关键在于如何取得所选中的CheckBox所在的行的一个唯一值。

设计视图代码如下:


程序代码 程序代码


<div id="NavBar"><asp:Image ID="Image1" runat="server" ImageUrl="~/Agents/Images/pico.gif" />您所在的位置:系统首页->物料清单->我的暂存架
</div>
<div id="WishListTitle"> 
    <asp:Label ID="lblAgtCode" runat="server" CssClass="cGreen"></asp:Label>的暂存架中,共有
    <asp:Label ID="lblNum" runat="server" Text="Label" CssClass="cRed"></asp:Label>
    条物料记录</div>
<div id="WishList">
    <asp:GridView ID="gdvWishList" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None" Width="100%" OnSelectedIndexChanged="gdvWishList_SelectedIndexChanged" OnRowDataBound="gdvWishList_RowDataBound" OnRowDeleting="gdvWishList_RowDeleting" OnRowUpdating="gdvWishList_RowUpdating" OnRowCancelingEdit="gdvWishList_RowCancelingEdit" OnRowEditing="gdvWishList_RowEditing" AutoGenerateColumns="False">
        <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
        <Columns>
            <asp:BoundField DataField="BoxID" HeaderText="ID" Visible="False" />
            <asp:TemplateField HeaderText="选择">
              
                <ItemTemplate>
                    <asp:CheckBox ID="ChkSelected"  runat="server" />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:BoundField DataField="MaterialCode" HeaderText="物料代码" ReadOnly="True">
                <ItemStyle HorizontalAlign="Left" VerticalAlign="Middle" />
            </asp:BoundField>
            <asp:BoundField DataField="MaterialName" HeaderText="物料名称" ReadOnly="True">
                <ItemStyle HorizontalAlign="Left" VerticalAlign="Middle" />
            </asp:BoundField>
            <asp:BoundField DataField="MaterialDesc" HeaderText="物料描述" ReadOnly="True">
                <ItemStyle HorizontalAlign="Left" VerticalAlign="Middle" />
            </asp:BoundField>
            <asp:BoundField DataField="MaterialUnitPrice" HeaderText="单价" ReadOnly="True">
                <ItemStyle HorizontalAlign="Left" VerticalAlign="Middle" />
            </asp:BoundField>
            <asp:BoundField DataField="MaterialOrderSum" HeaderText="数量">
                <ItemStyle ForeColor="Red" HorizontalAlign="Center" VerticalAlign="Middle" />
                <HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" />
            </asp:BoundField>
            <asp:CommandField EditText="修改数量" ShowEditButton="True" />
            <asp:CommandField DeleteText="<div id=d onclick="javascript:return confirm('你真的要删除这一物料吗?');">移除</div>" ShowDeleteButton="True" />
        </Columns>
        <RowStyle BackColor="#EFF3FB" />
        <EditRowStyle BackColor="Beige" />
        <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
        <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
        <HeaderStyle BackColor="Desktop" Font-Bold="True" ForeColor="White" />
        <AlternatingRowStyle BackColor="White" />
    </asp:GridView>
    <webdiyer:AspNetPager ID="AspNetPager1" runat="server" PageSize="22">
    </webdiyer:AspNetPager>
    <div id="ChkSelect">
        <asp:CheckBox ID="chkSelectAll" runat="server" Text="全部选中" AutoPostBack="True" OnCheckedChanged="chkSelectAll_CheckedChanged" />
        <asp:CheckBox ID="chkCancelAll" runat="server" Text="全部取消" AutoPostBack="True" OnCheckedChanged="chkCancelAll_CheckedChanged" />               
        <asp:ImageButton ID="imgbtGeneraOrder" runat="server" ImageUrl="~/Agents/Images/GenerateOrder_ico.gif" />        
        <asp:ImageButton ID="imgbtDelete" runat="server" ImageUrl="~/Agents/Images/delete_ico.gif" OnClick="imgbtDelete_Click" /></div>
    <br />
</div>


我们先来实现全部选中,我看了很多用JS来实现的方法,但个人还是觉得下面这样来得快些,可以看到

<asp:CheckBox ID="chkSelectAll" runat="server" Text="全部选中" AutoPostBack="True" OnCheckedChanged="chkSelectAll_CheckedChanged" />中,已经产生了OnCheckedChanged的事件,我们在其事件编写代码:


/// <summary>
    /// 全部选中
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void chkSelectAll_CheckedChanged(object sender, EventArgs e)
    {
        for (int i = 0; i <= gdvWishList.Rows.Count - 1; i++)
        {
            CheckBox cbox = (CheckBox)gdvWishList.Rows[i].FindControl("ChkSelected");
            if (chkSelectAll.Checked == true)
            {
                cbox.Checked = true;
            }
            else
            {
                cbox.Checked = false;
            }
        }

    }


同样,全部取消就只是把cbox.Checked的属性改为False就实现了

/// <summary>
    /// 全部取消
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void chkCancelAll_CheckedChanged(object sender, EventArgs e)
    {
        for (int i = 0; i <= gdvWishList.Rows.Count - 1; i++)
        {
            CheckBox cbox = (CheckBox)gdvWishList.Rows[i].FindControl("ChkSelected");
            if (chkCancelAll.Checked == true)
            {
                cbox.Checked = false;
            }
            
        }
    }



后面的两个我就做删除所选的物料这个事件吧


/// <summary>
    /// 批量删除CheckBox所选的物料
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void imgbtDelete_Click(object sender, ImageClickEventArgs e)
    {


        for (int i = 0; i < gdvWishList.Rows.Count; i++)
        {
            GridViewRow row = gdvWishList.Rows[i];
            bool isChecked = ((CheckBox)row.FindControl("ChkSelected")).Checked;

            int BoxID = Convert.ToInt32(gdvWishList.DataKeys[gdvWishList.Rows[i].DataItemIndex].Value);

            if (isChecked)
            {
                AgentOrderFlow.DeleteBoxMaterial(BoxID);
            }
        }


        
        ShowBoxList();
    }

特别注意的是这句:
  int BoxID = Convert.ToInt32(gdvWishList.DataKeys[gdvWishList.Rows[i].DataItemIndex].Value);
是获取CheckBox所在行中的一个可以称之为为“唯一键值"的方法,其实就是一个主键值.当然,在使用DataKeys之前,需要在绑定数据的时候定义您的DataKeyName ,如下:

protected void ShowBoxList()
    {
        string AID = Request.QueryString["AID"].ToString().Trim();

            Security sc = new Security();

            int agentId = Convert.ToInt32(sc.DecryptQueryString(AID));

            gdvWishList.DataSource = AgentOrderFlow.ShowMyBoxListByAgentId(agentId,AspNetPager1.PageSize,AspNetPager1.CurrentPageIndex);

            gdvWishList.DataKeyNames = new string[] { "BoxId" };

            gdvWishList.DataBind();
          
    }


上面三个应该是在使用CheckBox与GridView结合用得最多的几个方法吧,至于改变行的样式,这个只要在RowDataBound里面动动手脚就可以了

顺便贴过来

程序代码 程序代码


   /// <summary>
    /// 隔行变色
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void gdvWishList_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        int i;
        //执行循环,保证每条数据都可以更新
        for (i = 0; i < gdvWishList.Rows.Count; i++)
        {
            //首先判断是否是数据行
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                //当鼠标停留时更改背景色
                e.Row.Attributes.Add("onmouseover", "c=this.style.backgroundColor;this.style.backgroundColor='#E6F3F9'");
                //当鼠标移开时还原背景色
                e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor=c");
            }
        }

    }



查了一下Google,还有一些方法,归纳如下:(感谢提供以下方法的IT同行)

1.来源:http://blog.tiantiansoft.com/user1/9/archives/2006/2788.html

这个是用了Javascript来获取所选行的Checkbox的,不太推荐,看起来还是俺的好点


程序代码 程序代码


在GridView的第一列使用CheckBox控制每一行数据,是经常使用的,这里面我要记录的是全选、全消、选中行的底色更改,还有就是在提交数据的时候,取选中的行的编号等功能

aspx页面定义:

<asp:GridView ID="GridView1" runat="server">
        <Columns>
            <asp:TemplateField ShowHeader="False" HeaderText="选择">
                <ItemStyle Width="60px" Wrap="False" />
                <HeaderTemplate>
                    <asp:CheckBox ID="CheckBox1" runat="server"></asp:CheckBox>
                </HeaderTemplate>
                <ItemTemplate>
                    <asp:CheckBox ID="CheckBox1" runat="server"></asp:CheckBox>
                    <asp:TextBox ID="TextBox1" runat="server" Text='<%# Eval("EventID") %>' Visible="false"></asp:TextBox>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
        <HeaderStyle Font-Bold="False" BackColor="#EEEEEE" />
        <AlternatingRowStyle BackColor="#EEEEEE" />
</asp:GridView>
这样在GridView的第一列,是CheckBox控件,在HeaderTemplate里的是用来控制全选全消的,在TemplateField里的,用来控制当前行是不是选中行

js脚本是这个:


<script type="text/javascript" language="javascript">
function changecolor(obj,color)
{
   e = event.srcElement
   if(e.checked==true)
   {
     e = e.parentElement
     e.style.background = "#C0C0FF"
    }
    else
    {
      e = e.parentElement
      e.style.background = color
     }
}

function CheckSelect(del)
{
    var rt=true;
    var num=0;
    var boxorder=0;
    var objCheckBox;
    for(var i=0;i<aspnetForm.length;i++)
    {
        ///alert(aspnetForm.elements[i].type);
        if(aspnetForm.elements[i].type=="checkbox")
        {
            boxorder++;
            objCheckBox=aspnetForm.elements[i];
            ///alert(objCheckBox.checked);
            if(objCheckBox.checked)
            {
                if(boxorder>1)
                {
                    //如果是第一个CheckBox,是用来全选全消的,这个不算,不用自加
                    num++;
                }
            }
        }
    }
    ///alert(num);
    if(!del)
    {
        if(num>1)
        {
            alert("此操作不允许选择多个事件");
            rt=false;
        }
    }
    if(num==0)
    {
        alert("此操作要求先选择一个事件");
        rt=false
    }
    ///alert(rt);
    return rt;
}

function SelectAll(sa)
{
    ///全选/全消
    var objCheckBox;
    for(var i=0;i<aspnetForm.length;i++)
    {
        if(aspnetForm.elements[i].type=="checkbox")
        {
            objCheckBox=aspnetForm.elements[i];
            objCheckBox.checked=sa;
        }
    }
}
</script>

第一个函数changecolor用来控制被选择的行的颜色突出,第二个函数CheckSelect用来判断现在有几个行被选中,第三个函数SelectAll用来控制全选全消

在cs页面里,为每一行的CheckBox绑定客户端事件:


protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.Header || e.Row.RowType == DataControlRowType.DataRow)
        {
            CheckBox mycb = new CheckBox();
            mycb = (CheckBox)e.Row.FindControl("CheckBox1");
            if (mycb != null)
            {
                if (e.Row.RowType == DataControlRowType.DataRow)
                {
                    if (e.Row.RowIndex % 2 == 0)
                    {
                        mycb.Attributes.Add("onclick", "changecolor(this.name,'#FFFFFF')");
                    }
                    else
                    {
                        mycb.Attributes.Add("onclick", "changecolor(this.name,'#EEEEEE')");
                    }
                }
                else if (e.Row.RowType == DataControlRowType.Header)
                {
                    mycb.Attributes.Add("onclick", "SelectAll(this.checked)");
                }
            }
        }
    }
这里,对不同的DataControlRowType,我绑定了不同的客户端事件,因为定义在HeaderTemplate和ItemTemplate里的CheckBox是要执行不同的客户端事件的

上面的东西都很简单,分清楚客户端和服务器端就可以了,我一开始的时候在服务器端和客户端跳来跳去,自己都乱了,好烦啊

我在这里还要记录这样的情况:

在页面里,有一个自定义用户控件,有一个GridView控件,在自定义用户控件里,有Button用来控制GridView里的记录

我要记录的是,怎么在这个Button里,判断有哪些记录被选中

1、上面的aspx代码里,我加了TextBox,记录编号

2、在自定义用户控件里,用下面的事件,就返回选中行的编号了


public string GetEid()
    {
        //取选中的事件编号
        string streid = "";
        GridView mygv = new GridView();
        mygv = (GridView)Parent.FindControl("GridView1");
        if (mygv != null)
        {
            int i, row;
            i = 0;
            row = mygv.Rows.Count;
            CheckBox mycb = new CheckBox();
            for (i = 0; i < row; i++)
            {
                mycb = (CheckBox)mygv.Rows[i].FindControl("CheckBox1");
                if (mycb != null)
                {
                    if (mycb.Checked)
                    {
                        TextBox mytb = new TextBox();
                        mytb = (TextBox)mygv.Rows[i].FindControl("TextBox1");
                        if (mytb != null)
                        {
                            streid = streid + mytb.Text.Trim() + ",";
                        }
                    }
                }
            }
        }
        if (streid.Length > 0)
        {
            streid = streid.Remove(streid.Length - 1);
        }
        return streid;
    }
就是Parent和FindControl的使用,用Parent可以引用包含自定义用户控件的页面,对这个页面里的GridView的每一行扫描,就可以取到每一行的CheckBox了

对自定义控件里,如果有的Button需要先选择一个 or 多个记录才允许操作的,可以在自定义控件里给Button加上客户端事件

protected void Page_Load(object sender, EventArgs e)
    {
        Button1.Attributes["onclick"] = "return CheckSelect(false);";
        Button4.Attributes["onclick"] = "return CheckSelect(false);";
        Button2.Attributes["onclick"] = "return CheckSelect(true);";
    }



2.js取得gridview中获取checkbox选中的值

for( i=1;i<document.all.GVmain.rows.length;i++)
         {
            var cb=document.all.GVmain.rows(i).cells(0).children(0);
            if(cb.checked)
            {
                 temp0=document.all.GVmain.rows(i).cells(1).innerText;
                 temp1=document.all.GVmain.rows(i).cells(5).innerText;
                 temp2=document.all.GVmain.rows(i).cells(6).innerText;
              }
         }

也就这些了吧,当然,把Checkbox结合到gridview中作成扩展的控件又是另一回事了
posted @ 2009-02-27 11:11  单康丽  阅读(6597)  评论(0编辑  收藏  举报