在GridView中使用FindControl

最近项目中用到FindControl和GridView,整理了一下几种使用方法,留作资料。

1、在选择(SelectedIndexChanged)事件中使用


     //获得被选择行的TextBox1
    protected void gv1_SelectedIndexChanged(object sender, EventArgs e)
    {
        //Control c = this.gv1.Rows[this.gv1.SelectedIndex].FindControl("TextBox1");
        //TextBox tb = (TextBox)c;
        //tb.Text = "TextBox";

        TextBox tb = (TextBox)this.gv1.Rows[this.gv1.SelectedIndex].FindControl("TextBox1");
        tb.Text = "hello";
    }

 

2、在编辑行(RowEditing)事件中使用

   
    //编辑行时,找到TextBox1
    protected void gv1_RowEditing(object sender, GridViewEditEventArgs e)
    {
        //设置要编辑行的索引
        gv1.EditIndex = e.NewEditIndex;
        GridViewBind();

        TextBox tb = (TextBox)this.gv1.Rows[e.NewEditIndex].FindControl("TextBox1");
        Response.Write(tb.Text);
    }


3、在取消编辑行(RowCancelingEdit)事件中使用

    //取消编辑时,找到TextBox1
    protected void gv1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
    {
        TextBox tb = (TextBox)this.gv1.Rows[e.RowIndex].FindControl("TextBox1");
        Response.Write(tb.Text);

        gv1.EditIndex = -1;
        GridViewBind();
    }

 

4、在行绑定(RowDataBound)事件中使用

   

    //获得行数据绑定中的TextBox1
    protected void gv1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        // 对于在RowDataBound中Find,可以用if (e.Row.RowType == DataControlRowType.DataRow)来限制Find的范围,因为Find默认是在HeaderTemplate中找,如果不限定范围,在HeaderTemplate中找不到,自然就返回null,然后就出错了,DataControlRowType枚举中的DataRow确定是数据行.
        //if (e.Row.RowType == DataControlRowType.DataRow)
        //{
        //    TextBox tb = (TextBox)e.Row.FindControl("TextBox1");
        //    tb.Text = "databind";
        //}


        //如果在DataGrid的页眉和页脚:

        //if (e.Row.RowType == DataControlRowType.Header)
        //{
        //    TextBox tbheader = (TextBox)e.Row.FindControl("txtHeader");
        //    tbheader.Text = "Head";
        //}
        ((TextBox)this.gv1.Controls[0].Controls[0].FindControl("txtHeader")).Text = "Head";

        if (e.Row.RowType == DataControlRowType.Footer)
        {
            TextBox tbfooter = (TextBox)e.Row.FindControl("txtFooter");
            tbfooter.Text = "Footer";
        }
    }

 

5、在行命令(RowCommand)事件中使用

    

    //行命令时间中找到TextBox1
    //如果使用GridView默认的模式,e.CommandArgument自动棒定为该行的Index,这时候只要指定gridview1.Rows[Convert.ToInt32(e.CommandArgument)].FindControl("xxx")就可以了,但是如果转化为Template,e.CommandArgument并不会自动绑定任何值,需要手动绑定,可以在<ItemTemplate></ItemTemplate>手动写CommandArgument="<%# ((GridViewRow) Container).RowIndex %>",把这个行的 Index绑定绑定到该e.CommandArgument就可以了.
    protected void gv1_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        if (e.CommandName.ToLower() == "change")
        {
            TextBox tb = (TextBox)this.gv1.Rows[Convert.ToInt32(e.CommandArgument)].FindControl("TextBox1");
           
            Response.Write(tb.Text);
        }
    }

 

其他事件中的使用,和上面列举的类似

附上,前台代码:UseTest3.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="UseTest3.aspx.cs" Inherits="UseTest3" %>

<!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>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:GridView ID="gv1" runat="server" AutoGenerateColumns="False" OnSelectedIndexChanged="gv1_SelectedIndexChanged" OnRowEditing="gv1_RowEditing" OnRowDataBound="gv1_RowDataBound" ShowFooter="True" OnRowCommand="gv1_RowCommand" DataKeyNames="employeeid" OnRowCancelingEdit="gv1_RowCancelingEdit">
        <Columns>
        <asp:TemplateField>
            <HeaderTemplate>
                <asp:TextBox ID="txtHeader" runat="Server"></asp:TextBox>
            </HeaderTemplate>
            <ItemTemplate>
                <asp:TextBox ID="TextBox1" Text='<%# Bind("employeeid")%>' runat="server"></asp:TextBox>            
            </ItemTemplate>
            <FooterTemplate>
                <asp:TextBox ID="txtFooter" runat="server"></asp:TextBox>
            </FooterTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="lastname" HeaderText="LastName" />
        <asp:BoundField DataField="firstname" HeaderText="FirstName" />
        <asp:ButtonField CommandName="select" Text="选择" />    
        <asp:ButtonField CommandName="change" Text="change" />
            <asp:CommandField ShowEditButton="True" />
        </Columns>
        </asp:GridView>
        &nbsp;</div>
    </form>
</body>
</html>

 

阅读更多
换一批

GridView里的FindControl问题

06-25

我在做一个评教的页面,简单的说就是有一系列问题,每个问题有5个选项,问题分为好几类。rn存储问题的数据表的结构是:rn ID ClassID OrderID QContentrn 索引编号 分类ID 类别下的排序ID 问题内容rnrn一共有23个问题,因为这些问题的内容和顺序可能被更改,所以采用数据表的方式存储。rnrn涉及我的问题的部分代码是:rn[code=C#]rnprivate static readonly string strConn = ConfigurationManager.ConnectionStrings["CIMSConnectionString"].ConnectionString;rnrnprotected void Page_Load(object sender, EventArgs e)rnrn if (!IsPostBack) //初始化名为QList的GridViewrn rn QList.AutoGenerateColumns = false;rn QList.ShowHeader = false;rnrn BoundField bndCol = new BoundField();rn bndCol.DataField = "OrderID";rn QList.Columns.Add(bndCol);rnrn bndCol = new BoundField();rn bndCol.DataField = "QContent";rn QList.Columns.Add(bndCol);rn rnrn SqlConnection conn = new SqlConnection(strConn);rn SqlCommand cmd = new SqlCommand("SELECT OrderID, QContent FROM [QList] ORDER BY ClassID, OrderID", conn);rn conn.Open();rn SqlDataReader dr = cmd.ExecuteReader();rnrn QList.RowDataBound += new GridViewRowEventHandler(QList_RowDataBound);rn QList.DataSource = dr;rn QList.DataBind();rnrn dr.Close();rn conn.Close();rnrnpublic static readonly string[] SORT = new string[] "OVEROLL QUESTION","SPECIFIC QUESTION","INSTRUCTOR QUESTION"; //问题分类rnrnpublic int Si = 0, sort = 0, [b]rblid = 0[/b];rnrnprivate void QList_RowDataBound(object sender, GridViewRowEventArgs e)rnrn if (e.Row.RowIndex >= 0)rn rn if (e.Row.Cells[0].Text == "1") //遇到OrderID为1,就添加新的问题分类rn rn GridViewRow rs1 = new GridViewRow(0, 0, DataControlRowType.DataRow, DataControlRowState.Normal);rn TableCell sc1 = new TableCell();rn sc1.ColumnSpan = 2;rn sc1.HorizontalAlign = HorizontalAlign.Center;rn sc1.Text = SORT[Si];rn rs1.Cells.Add(sc1);rn rs1.Visible = true;rn QList.Controls[0].Controls.AddAt(e.Row.RowIndex + sort + 1, rs1);rn Si++;rn sort++;rn rn //给每个问题添加RadioButtonList控件rn GridViewRow rs = new GridViewRow(0, 0, DataControlRowType.DataRow, DataControlRowState.Normal);rn TableCell sc = new TableCell();rn sc.ColumnSpan = 2;rn sc.HorizontalAlign = HorizontalAlign.Right;rn RadioButtonList rbl = new RadioButtonList();rn [b]rbl.ID = "rbl_" + rblid.ToString();[/b]rn rbl.RepeatDirection = RepeatDirection.Horizontal;rn rbl.Items.Add(new ListItem("5", "5"));rn rbl.Items.Add(new ListItem("4", "4"));rn rbl.Items.Add(new ListItem("3", "3"));rn rbl.Items.Add(new ListItem("2", "2"));rn rbl.Items.Add(new ListItem("1", "1"));rn sc.Controls.Add(rbl);rn rs.Cells.Add(sc);rn rs.Visible = true;rn QList.Controls[0].Controls.AddAt(e.Row.RowIndex + sort + 2, rs);rn sort++;rn rblid++;rn rnrn[/code]rnrn生成的GridView很标准,但是当提交的时候,我需要用FindControl方法来定位每一个RadiaoButtonList以获取选定的值。代码是这样的。rn[code=C#]rnprotected void btn_submit1_Click(object sender, EventArgs e)rnrn bool IsLegal = true; //这个是用来判断是否是所有题都有选项rn ArrayList aln =new ArrayList();rnrn for (int i = 0; IsLegal && i != 23; i++)rn rn [b]RadioButtonList rbl = (RadioButtonList)FindControlEx(QList, "rbl_" + i.ToString());[/b]rn if (rbl.SelectedValue.ToString() == "")rn rn IsLegal = false;rn rn elsern rn ......rn rn aln.Add(subdata);rn rnrnrnpublic Control FindControlEx(Control Parent, string id)rnrn Control oCtrl = null;rn oCtrl = Parent.FindControl(id);rn if (oCtrl == null && Parent.Controls.Count > 0)rn rn foreach (Control oChildCtrl in Parent.Controls)rn rn oCtrl = FindControlEx(oChildCtrl, id);rn if (oCtrl != null) break;rn rn rn return oCtrl;rnrn[/code]rnrn问题是,加粗的那一行,也就是用 递归方式的FindControl方法(FindControlEx) 的那一行。rnrbl无论如何总是定位到第一个RadioButtonList上(ID为rbl_0)rn我尝试更改参数,即使string id这个参数为""(空值),或者为任意字符串,rbl同样也被定位到rbl_0上。rnrn我在单独的页面里测试过FindControlEx,可以正常地返回null值或者对应ID的控件。rnrn这个问题已经困扰我好几天了,希望大家可以帮我找一下问题……rn

没有更多推荐了,返回首页