Gridview row.Cells[i].Findcontrol 在错误的单元格中查找控件

Gridview row.Cells[i].Findcontrol finding control in wrong Cell

我有一个我编写的函数,您传入 gridview 行,以及您试图定位的控件类型。它按预期找到了控件,但是,它在错误的单元格中找到了它。

protected int GetCell(GridViewRow row, string strSection)
{
    int intVal = 0;
    for (int i = 0; i < row.Cells.Count; i++)
    {
        intVal = i;
        if (strSection == "QueryRate")
        {
            DropDownList cmbQueryType = row.Cells[i].FindControl("cmbQueryType") as DropDownList;
            if (cmbQueryType != null)
            {
                break;
            }
        }
        else if (strSection == "Name")
        {
            TextBox txtName = row.Cells[i].FindControl("txtName") as TextBox;
            if (txtName != null)
            {
                break;
            }
        }
    }
    return intVal;
}

根据我的理解,直接来自 Microsoft 页面:使用指定的 id 参数搜索服务器控件的 当前 命名容器。

所以我的问题是,为什么这个看似找到控件的列是错误的?我无法对特定列进行硬编码,因为显示的列因数据源而异。

根据请求,网格视图:

<TDWeb:PageGridView SkinID="pagegrid" EmptyDataText="No unmatched parameters."  ID="gvUnmatched"  runat="server"  AllowSorting="True" 
                            OnSorting="gvUnmatched_Sorting" AutoGenerateColumns="False"  OnRowDataBound="gvUnmatched_RowDatabound"  OnDataBound="gvUnmatched_DataBound"
                            OnPreRender="gvUnmatched_PreRender" OnPageIndexChanging="OnFilterUnmatched" DataKeyNames="InternalName"
                            ShowFooter="true" OnPageSizeChanged="gvUnmatched_PageSizeChanged">
                    <Columns>
                        <asp:TemplateField runat="server" ItemStyle-CssClass="c" FooterStyle-CssClass="c">
                            <HeaderTemplate>
                                <asp:Label runat="server" Text="Add" />
                                <asp:CheckBox runat="server" ID="ckbAddAll" />
                            </HeaderTemplate>
                            <ItemTemplate>
                                <asp:CheckBox runat="server" ID="ckbAdd" EnableViewState="true" />
                            </ItemTemplate>
                        </asp:TemplateField>
                        <asp:TemplateField runat="server" ItemStyle-CssClass="c">
                            <HeaderTemplate>
                                <asp:Label runat="server" Text="Ignore" />
                                <asp:CheckBox runat="server" ID="ckbIgnoreAll" />
                           </HeaderTemplate>
                           <ItemTemplate>
                               <asp:CheckBox runat="server" ID="ckbIgnore" />
                           </ItemTemplate>
                        </asp:TemplateField>
                        <asp:TemplateField runat="server" HeaderText="Name" SortExpression="Name" ItemStyle-CssClass="l">
                            <HeaderTemplate>
                                <asp:LinkButton runat="server" Text="Name" CommandName="Sort" CommandArgument="Name" />
                                <td:HelperBox ID="HelperBox5" runat="server" ToolTipText="Set the Name for this parameter. This value must be unique to the CAN Bus or ECU and is the value used throughout the DAP system to reference this parameter." />
                            </HeaderTemplate>
                            <ItemTemplate>
                                <asp:TextBox runat="server" ID="txtName" Width="250" MaxLength="256" style="background-color:inherit" Text='<%# Bind("Name") %>' /> 
                            </ItemTemplate>
                        </asp:TemplateField>
                        <asp:TemplateField runat="server" ItemStyle-CssClass="l" SortExpression="Description">
                            <HeaderTemplate>
                                <asp:LinkButton runat="server" Text="Description" CommandName="Sort" CommandArgument="Description" />
                                <td:HelperBox ID="HelperBox4" runat="server" ToolTipText="Set the Description for this parameter. This value is for informational purposes only. Not required." />
                            </HeaderTemplate>
                            <ItemTemplate>
                                <asp:TextBox runat="server" ID="txtDescription" Width="175" MaxLength="500" 
                                    TextMode="multiline" style="background-color:inherit" Text='<%# Bind("Description") %>' /> 
                            </ItemTemplate>
                        </asp:TemplateField>
                        <asp:TemplateField runat="server" HeaderText="Length (bits)" SortExpression="LengthBits" ItemStyle-CssClass="r">
                            <ItemTemplate>
                                <asp:Label runat="server" ID="txtSizeBits" Text='<%# (int)Eval("LengthBits") + (int)Eval("LengthBytes") * 8 %>' style="background-color:inherit" /> 
                            </ItemTemplate>
                        </asp:TemplateField>
                        <asp:TemplateField runat="server" AccessibleHeaderText="SourceAddress" HeaderText="SA" SortExpression="Sources" ItemStyle-CssClass="r">
                            <ItemTemplate>
                                <asp:Label runat="server" ID="txtSources" Text='<%# Eval("SourceString") %>' /> 
                            </ItemTemplate>
                        </asp:TemplateField>
                        <asp:TemplateField runat="server" AccessibleHeaderText="ID" HeaderText="ID/Address" SortExpression="IDorAddress" ItemStyle-CssClass="r">
                            <ItemTemplate>
                                <asp:Label runat="server" ID="txtIDorAddress" Text='<%# Eval("IDorAddress") %>' /> 
                            </ItemTemplate>
                        </asp:TemplateField>
                        <asp:TemplateField runat="server" HeaderText="Data Type" SortExpression="Datatype" ItemStyle-CssClass="l">
                            <ItemTemplate>
                                <asp:Label runat="server" ID="txtDatatype" Text='<%# Bind("Datatype") %>' /> 
                            </ItemTemplate>
                        </asp:TemplateField>
                        <asp:TemplateField runat="server" AccessibleHeaderText="QueryRate" ItemStyle-CssClass="r" SortExpression="QueryRate" HeaderText="Query Rate">
                            <HeaderTemplate>
                                <asp:Label runat="server" Text="Rate" />
                                <td:HelperBox ID="HelperBox9" runat="server" ToolTipText="Set the Query Type and Rate for this parameter (if applicable). If set, this value overrides the default Query set below." />
                            </HeaderTemplate>
                            <ItemTemplate>
                                <asp:Label runat="server" ID="lblCANRate" Text='<%# Eval("QueryRateString", "{0} s") %>' Visible='<%# m_SelectedFile.ImportType == App_Code.DAPConfig.ParameterFileImport.EImportType.CANDBC || (m_SelectedFile.ImportType == App_Code.DAPConfig.ParameterFileImport.EImportType.J1939DBC && ((int)Eval("QueryRate")) > 0) %>' />
                                <asp:DropDownList runat="server" ID="cmbQueryType" style="background-color:inherit" Visible='<%# m_SelectedFile.ImportType != App_Code.DAPConfig.ParameterFileImport.EImportType.CANDBC && (m_SelectedFile.ImportType != App_Code.DAPConfig.ParameterFileImport.EImportType.J1939DBC || (int)Eval("QueryRate") <= 0) %>' />
                                <asp:Panel runat="server" id="pnlRate" style="display:none" ><asp:TextBox runat="server" ID="txtRate" Width="50" MaxLength="6" style="background-color:inherit" />s</asp:Panel>
                            </ItemTemplate>
                        </asp:TemplateField>
                        <asp:TemplateField runat="server" HeaderText="Category" ItemStyle-CssClass="l">
                            <HeaderTemplate>
                                <asp:Label runat="server" Text="Category" />
                                <td:HelperBox ID="HelperBox10" runat="server" ToolTipText="Set the Category with which to group this parameter, or create a new category." />
                            </HeaderTemplate>
                            <ItemTemplate>
                                <asp:DropDownList runat="server" ID="cmbCategory" style="background-color:inherit" >
                                    <asp:ListItem Value="_New_" Text="Add New..." />
                                </asp:DropDownList>
                                <br />
                                <asp:TextBox Width="100" MaxLength="50" runat="server" ID="txtCategory" style="display:none;background-color:inherit" />
                            </ItemTemplate>
                        </asp:TemplateField>
                   </Columns>
               </TDWeb:PageGridView>

如果您知道要查找的控件的 ID,则无需指定单元格。你可以通过查看整行找到它。

DropDownList cmbQueryType = row.FindControl("cmbQueryType") as DropDownList 

这样可以避免单元格索引不正确的问题。

ok - 结果调用 row.cells(0).FindControl("") 等同于调用 row.FindControl(""),因为 FindControl() 在当前 NamingContainer 中运行。并且给定行中的所有单元格都具有相同的 NamingContainer,特别是 {System.Web.UI.WebControls.GridViewRow}

如果您只需要确定给定控件的列索引,请试试这个(请原谅 VB):

Public Function getCellIndexByName(ByVal row As GridViewRow, ByVal ColumnName As String) As Integer
    For ci As Integer = 0 To row.Cells.Count - 1
        If CType(row.Cells(ci), DataControlFieldCell).ContainingField.ToString() = ColumnName Then
            Return ci
        End If
    Next

    Return -1
End Function