【问题标题】:How do I get value of field in nested gridview where checkbox is checked?如何在选中复选框的嵌套网格视图中获取字段值?
【发布时间】:2014-11-06 00:27:22
【问题描述】:

我在另一个 gridview 中有一个嵌套的 gridview。父 gridview 有一个任务列表,每个任务都有一个步骤列表(子 gridview)。每个步骤都有一个复选框,因此一旦用户完成一个步骤,他将选中该复选框,这将触发 CheckChanged 事件,在该事件中我有一个存储过程来更新数据库,因此选中的步骤注册为已完成。

我有一个 CheckChanged 事件,它查找选中复选框所在行的步骤 ID,然后使用步骤 ID 作为输入参数触发存储过程。这行得通。但是,可以添加步骤,并且由于某种原因,当单击较早步骤上的复选框时,查找步骤 ID 的代码不会返回并识别步骤 ID。换句话说,如果某个任务的步骤 ID 为 20,并且它被检查并且事件触发,如果我将一个步骤添加到较早的任务(gridview 上列出的任务)并且该步骤具有ID 为 21,单击它会不断将步骤 ID 注册为 20,就好像 CheckChanged 事件无法识别添加到另一个任务的步骤一样。这是我的代码:

aspx:

<asp:GridView ID="GridView1" 
                DataKeyNames="TaskID" 
                runat="server" 
                OnRowDataBound="GridView1_OnRowDataBound" 
                CssClass="DefaultGrid" 
                onRowCommand="GridView1_RowCommand" 
                EmptyDataText = "<br/>There are no Tasks in this Project." 
                AllowPaging="True" 
                AllowSorting="True" 
                CellPadding="4" 
                DataSourceID="SqlDataSource_mp_Display_Tasks_Home" 
                ForeColor="#333333" 
                GridLines="None" 
                AutoGenerateColumns="False">
    <AlternatingRowStyle BackColor="White" ForeColor="#284775" />
    <RowStyle CssClass=" table-responsive body-content " />
    <Columns>
        <asp:CommandField ShowSelectButton="False" />          
        <asp:TemplateField>
            <ItemTemplate>
                <img alt = "" style="cursor: pointer" src="Images/plus.png" />                                           
                <asp:Panel ID="pnlOrders" runat="server" Style="display:none">                                          
                    <asp:GridView ID="GridView2" 
                                    runat="server" 
                                    onRowCommand="GridView2_RowCommand"  
                                    Datakeynames="TaskStepID"
                                    CssClass="ChildGrid" 
                                    EmptyDataText="<br/>There are no Steps in this Task." 
                                    AutoGenerateColumns="false" 
                                    onselectedindexchanged="GridView2_SelectedIndexChanged">
                        <Columns>                                                                     
                            <asp:BoundField DataField="TaskStepID" HeaderText="TaskStepID" Visible="true" />
                            <asp:BoundField DataField="TaskID" HeaderText="TaskID" Visible="false" />
                            <asp:BoundField DataField="TaskStepTypeID" HeaderText="TaskStepTypeID" Visible="false"/>
                            <asp:BoundField DataField="TaskStepPriority" HeaderText="Task Step Priority" Visible="false" />
                            <asp:BoundField ItemStyle-Width="70%" DataField="TaskStepDesc" HeaderText="Step Description" />                                   
                            <asp:TemplateField HeaderText="Step Completed" ItemStyle-Width="15%"  >
                                <ItemStyle HorizontalAlign="Center" />
                                <ItemTemplate>  
                                    <asp:Checkbox  ID="TaskStepCompleted"  
                                                    OnCheckedChanged="TaskStepCompleted_CheckedChanged" 
                                                    Checked='<%# Eval("TaskStepCompleted") %>' 
                                                    runat="server"                                                                                                                      
                                                    AutoPostBack="true" />                                                          
                                </ItemTemplate>                                                            
                            </asp:TemplateField>
                            <asp:BoundField DataField="TaskStepComment" HeaderText="TaskStepComment" Visible="false" />
                            <asp:TemplateField HeaderText="Step Activity" ItemStyle-Width="15%">
                                <ItemTemplate>       
                                    <asp:LinkButton Text="Add" ID="Addstep" runat="server" CommandName="addstep" CommandArgument='<%# Eval("TaskStepID") %>'/>
                                    <asp:LinkButton Text="Edit" ID="Editstep" runat="server" CommandName="editstep" CommandArgument='<%# Eval("TaskStepID") %>'/>                                                              
                                    <asp:LinkButton Text="Delete" ID="Deletestep" runat="server" CommandName="deletestep" OnClientClick="return confirm('<%=AlertMe%>');" CommandArgument='<%# Eval("TaskStepID") %>'/>                                                                                                   
                                </ItemTemplate>                                                            
                            </asp:TemplateField>
                        </Columns>
                    </asp:GridView>
                </asp:Panel>
            </ItemTemplate>
        </asp:TemplateField>  
        <asp:BoundField DataField="TaskID" HeaderText="Task ID" Visible="false"/> 
        <asp:BoundField DataField="ProjectID" HeaderText="Project ID" Visible="false" />               
        <asp:BoundField DataField="TaskTypeID" HeaderText="Task Type ID"  Visible="false" />
        <asp:BoundField DataField="TaskCompleted" HeaderText="Taske Completed?" Visible="false"  />                
        <asp:BoundField DataField="TaskCreationDate" HeaderText="Task Creation Date" Visible="false"  />
        <asp:BoundField DataField="TaskSubmitterID"  HeaderText="Task Submitter ID" Visible="false"  />
        <asp:BoundField DataField="DepartmentID" HeaderText="DepartmentID" Visible="false"  />
        <asp:BoundField DataField="TaskDueDateCommentType" HeaderText="Due Date Comment" Visible="false"  />
        <asp:BoundField DataField="TaskLastUpdatedDate" HeaderText="Task Last Updated Date" Visible="false"  />
        <asp:BoundField DataField="TaskLastUpdatedUserID" HeaderText="Task Last Updated UserID" Visible="false"  />                
        <asp:BoundField DataField ="TaskSubmitterName" HeaderText="Task Submitter Name" Visible="false"  />
        <asp:BoundField DataField="TaskLastUpdatedUser" HeaderText="Task Last Updated User" Visible="false"  />                
        <asp:BoundField DataField="DepartmentDesc" HeaderText="Dept" visible="false"/>
        <asp:TemplateField HeaderText="Task Description">
            <ItemTemplate>
                <asp:Label ID="TaskDescription" runat="server" Text='<%# HighlightText(Eval("TaskDescription").ToString()) %>'></asp:Label>
            </ItemTemplate>
            <ItemStyle Width="40%" />
        </asp:TemplateField>
        <asp:TemplateField HeaderText="% Comp.">
            <ItemStyle HorizontalAlign="Center" />
            <ItemTemplate>
                <asp:Label ID="PercentCompleted" runat="server" Text='<%# (String.IsNullOrEmpty(Eval("PercentCompleted").ToString()) ? "0" : Eval("PercentCompleted")) + " %" %>' ></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="TaskDueDate" HeaderStyle-HorizontalAlign="Right" HeaderText="Task Due Date" DataFormatString="{0:MM-dd-yyyy}" visible="true"/> 
        <asp:BoundField DataField="TaskTypeName" HeaderText="Task Type" visible="true" />
        <asp:BoundField DataField="DepartmentAbbrev" HeaderText="Dept" Visible="true"  /> 
        <asp:TemplateField HeaderText="Activity">
            <ItemTemplate>       
            <asp:LinkButton Text="Edit" ID="Edittask" runat="server" CommandName="edittask" CommandArgument='<%# Eval("TaskID") %>'/>                                                              
            <asp:LinkButton Text="Delete" ID="Deletetask" runat="server" CommandName="deletetask" OnClientClick="return confirm('Are you sure you wish to Delete this Task?');" CommandArgument='<%# Eval("TaskID") %>'/>                                                                                                   
            <asp:LinkButton Text="Comments" ID="Detailstask" runat="server" CommandName="detailstask" CommandArgument='<%# Eval("TaskID") %>'/>  
            </ItemTemplate>                                                            
        </asp:TemplateField>
    </Columns>           
    <EditRowStyle BackColor="#999999" />
    <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
    <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
    <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
    <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
    <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
    <SortedAscendingCellStyle BackColor="#E9E7E2" />
    <SortedAscendingHeaderStyle BackColor="#506C8C" />
    <SortedDescendingCellStyle BackColor="#FFFDF8" />
    <SortedDescendingHeaderStyle BackColor="#6F8DAE" />
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource_mp_Display_Tasks_Home" runat="server" FilterExpression="TaskDescription LIKE '%{0}%'" ConnectionString="<%$ ConnectionStrings:IntelliBaseConnectionString_mp_Display_Projects_Home %>" SelectCommand="mp_Display_Tasks_Home" SelectCommandType="StoredProcedure" ProviderName="System.Data.SqlClient">
    <SelectParameters>
        <asp:Parameter Name="Incoming_ProjectID" Type="Int32" />                          
    </SelectParameters>
    <FilterParameters>
        <asp:ControlParameter Name="TaskDescription" ControlID="txtSearchtasks" PropertyName="Text"/>
    </FilterParameters>
</asp:SqlDataSource>

cs:

protected void TaskStepCompleted_CheckedChanged(object sender, EventArgs e)
{
    // this nested foreach grabs the taskstepID number for the row in which the checkbox was just checked.
    foreach (GridViewRow row in GridView1.Rows)
    {
        if (row.RowType == DataControlRowType.DataRow)
        {
            GridView GridView2 = (GridView)row.FindControl("GridView2");

            if (GridView2 != null)
            {
                foreach (GridViewRow Row in GridView2.Rows)
                {
                    if (Row.RowType == DataControlRowType.DataRow)
                    {
                        System.Web.UI.WebControls.CheckBox chk = (System.Web.UI.WebControls.CheckBox)Row.FindControl("TaskStepCompleted");
                        if (chk.Checked || !chk.Checked)
                        {
                            Session["TaskStepID"] = GridView2.DataKeys[Row.RowIndex]["TaskStepID"].ToString();
                        }
                    }
                }
            }
        }
    }

    // autopost back the check box to run the stored procedure
    var TaskStepID = Session["TaskStepID"].ToString();
    var ProjectID = Session["ProjectID"].ToString();

    using (var conn = new SqlConnection("Data Source=orlandosql1;Initial Catalog=IntelliBase;Persist Security Info=True;User ID=trainingsurveys_webuser;Password=C@mb3rSQL;"))
    using (SqlCommand cmd = new SqlCommand("dbo.mp_Task_Step_Completed_Toggle", conn))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add("@TaskStepID", SqlDbType.Int).Value = TaskStepID;
        cmd.Parameters.Add("@AdminUserID", SqlDbType.Int).Value = "10";
        cmd.Parameters.Add("@LogActionItemID", SqlDbType.Int).Value = "15";
        cmd.Parameters.AddWithValue("@DTStamp", SqlDbType.DateTime.ToString("d")).Value = DateTime.Now.ToString("d");

        conn.Open();
        cmd.ExecuteNonQuery();
        conn.Close();

        Response.Redirect("Tasks.aspx?id=" + ProjectID.ToString());
    }           
}

我已尽力描述问题。回顾一下:嵌套的 gridview 有带有复选框的行。点击复选框会自动更新 db 表,但不管复选框行,CheckedChanged 代码只会注册最近 ID 的 ID。任何见解都值得赞赏。

卡洛斯

【问题讨论】:

    标签: c# asp.net gridview checkbox


    【解决方案1】:

    如果我理解正确,我相信您的问题在于您认为自己如何获取 GridViewRow 的 TaskStepID。你正在做很多不必要的工作。无需迭代两个 GridView 的每一行,只需抓取刚刚单击的 CheckBox 的 GridViewRow。

    CheckBox cb = (CheckBox)sender;
    GridViewRow row = (GridViewRow)cb.NamingContainer;
    GridView gv = (GridView)row.NamingContainer;
    string taskStepID = gv.DataKeys[row.RowIndex].Value.ToString();
    

    请注意,通过像你一样迭代每一行,你总是得到最后一行的TaskStepID。因此,当您在它之前添加一行时,它使用的是最后一行而不是您预期的那一行。

    【讨论】:

    • 这正是我的问题!这看起来是查找行索引的更好解决方案。但是,Gridview2 是断章取义的。我如何能够在不需要迭代两个网格视图中的每一行的情况下将其置于上下文中?
    • 很好,很抱歉。检查我的编辑。您要做的是找到控件的 NamingContainer 以获取行。然后找到该行的NamingContainer,得到GridView。 NamingContainer 将沿着控件树向上,直到找到实现 INamingContainer 的控件。
    猜你喜欢
    • 1970-01-01
    • 2015-01-29
    • 2011-03-02
    • 2017-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-06
    相关资源
    最近更新 更多