FindControl 方法无法找到页面上的控件

发布于 2024-08-08 15:08:12 字数 6030 浏览 6 评论 0原文

我已经尝试搜索几个小时了,但无法找出为什么我的代码(又名我。)失败

基本上...我有一个列表视图控件,我正在传递产品的数据表(ID、名称、描述和价格列),我试图做到这一点,以便当按下“结帐”按钮时,它会解析页面上的所有控件,找到具有正确 ID 的所有控件并将项目值添加到购物车。

我检查了源代码中的所有 ID,它们与 FindControl 方法所请求的 ID 相匹配。

被抛出的错误是:

Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 
Line 21:         For I = 1 To counter
Line 22:             Dim cartItem As New Core.Types.CartItem
Line 23:             cartItem.Name = CType(productsContainer.FindControl("product" + I.ToString()), HtmlGenericControl).InnerText
Line 24:             cartItem.Quantity = Convert.ToInt32(CType(productsContainer.FindControl("quantity" + I.ToString()), HtmlSelect).Value)
Line 25:             cartItem.Price = Convert.ToDecimal(CType(productsContainer.FindControl("price" + I.ToString()), HtmlGenericControl).InnerText.Remove(0, 1))

我的 .aspx 代码:

                <div class="productsContainer" id="productsContainer" runat="server">
                <asp:ListView runat="server" ID="lsvProducts">
                    <LayoutTemplate>
                        <ul class="lsvProducts">
                            <li class="highlight">
                                <div class="productName">
                                    Product
                                </div>
                                <div class="productQuantity">
                                    Number of Licenses
                                </div>
                                <div class="productPrice">
                                    Price
                                </div>
                            </li>
                            <asp:PlaceHolder ID="itemPlaceHolder" runat="server"></asp:PlaceHolder>
                        </ul>
                    </LayoutTemplate>
                    <ItemTemplate>
                        <li>
                        <div style="display: none;">
                            <%=setCurrent()%>
                        </div>
                        <input type="hidden" id='productID<%#Eval("ID")%>' />
                            <div class="productName" id='product<%=currentItem%>'>
                                <%#Eval("Name")%>
                            </div>
                            <div class="productQuantity">

                            <select id='quantity<%=currentItem%>'>
                                <option selected="selected"
                                value="0">0</option>
                                <option value="1">1</option>
                                <option value="2">2</option>
                                <option value="3">3</option>
                                <option value="4">4</option>
                                <option value="5">5</option>
                                <option value="6">6</option>
                                <option value="7">7</option>
                                <option value="8">8</option>
                                <option value="9">9</option>
                                <option value="10">10</option>
                            </select>
                            </div>
                            <div class="productPrice" id='price<%=currentItem%>'>
                                <%#"$" + Convert.ToDouble(Eval("Price")).ToString()%>
                            </div>
                        </li>
                    </ItemTemplate>
                </asp:ListView>
            </div>
            <div class="clearer">
                &nbsp;</div>
            <div class="purchaseButton">
                <asp:Button ID="btnAddCart" runat="server" Text="Add to Cart" />
            </div>
        </div>

以及我后面的代码:

    Dim counter As Int32
Public currentItem As Int32

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    'get all active products to display in the listing
    Dim query As String = "SELECT * FROM Products WHERE Active = 1"
    Dim dt As DataTable = DAL.Data.GetDataTable(query, "MainDB")
    counter = dt.Rows.Count
    lsvProducts.DataSource = dt
    lsvProducts.DataBind()
End Sub

Protected Sub btnAddCart_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnAddCart.Click
    'create a new instance of the cart
    Dim cart As New Core.Types.Cart

    'foreach item in the listing, find its details and add it to the shopping cart
    For I = 1 To counter
        Dim cartItem As New Core.Types.CartItem
        cartItem.Name = CType(productsContainer.FindControl("product" + I.ToString()), HtmlGenericControl).InnerText
        cartItem.Quantity = Convert.ToInt32(CType(productsContainer.FindControl("quantity" + I.ToString()), HtmlSelect).Value)
        cartItem.Price = Convert.ToDecimal(CType(productsContainer.FindControl("price" + I.ToString()), HtmlGenericControl).InnerText.Remove(0, 1))
        cartItem.ID = Convert.ToInt32(CType(productsContainer.FindControl("productID" + I.ToString()), HtmlGenericControl).InnerText)
        cart.AddItem(cartItem)
    Next

    If (cart.isEmpty) Then
        'empty cart, go nowhere. show a message saying the carts empty and to choose something.
    Else
        Response.Redirect("~/Checkout.aspx")
    End If
End Sub

Public Function setCurrent()
    currentItem = currentItem + 1
    Return currentItem
End Function

请帮忙...这让我发疯!

提前致谢 :)

Ive tried searching for hours now and cannot find out why my code (aka, me.) is failing

Basically... I have a listview control which I'm passing a datatable of products (ID, Name, Description and Price columns), and im trying to make it so that when the "checkout" button is pressed, it parses through all the controls on the page, finds all the controls with the correct ID's and adds the items values to the cart.

ive checked all my ID's in the source code and they match up to the ones being requested by the FindControl method.

the error getting thrown back is:

Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 
Line 21:         For I = 1 To counter
Line 22:             Dim cartItem As New Core.Types.CartItem
Line 23:             cartItem.Name = CType(productsContainer.FindControl("product" + I.ToString()), HtmlGenericControl).InnerText
Line 24:             cartItem.Quantity = Convert.ToInt32(CType(productsContainer.FindControl("quantity" + I.ToString()), HtmlSelect).Value)
Line 25:             cartItem.Price = Convert.ToDecimal(CType(productsContainer.FindControl("price" + I.ToString()), HtmlGenericControl).InnerText.Remove(0, 1))

my .aspx code:

                <div class="productsContainer" id="productsContainer" runat="server">
                <asp:ListView runat="server" ID="lsvProducts">
                    <LayoutTemplate>
                        <ul class="lsvProducts">
                            <li class="highlight">
                                <div class="productName">
                                    Product
                                </div>
                                <div class="productQuantity">
                                    Number of Licenses
                                </div>
                                <div class="productPrice">
                                    Price
                                </div>
                            </li>
                            <asp:PlaceHolder ID="itemPlaceHolder" runat="server"></asp:PlaceHolder>
                        </ul>
                    </LayoutTemplate>
                    <ItemTemplate>
                        <li>
                        <div style="display: none;">
                            <%=setCurrent()%>
                        </div>
                        <input type="hidden" id='productID<%#Eval("ID")%>' />
                            <div class="productName" id='product<%=currentItem%>'>
                                <%#Eval("Name")%>
                            </div>
                            <div class="productQuantity">

                            <select id='quantity<%=currentItem%>'>
                                <option selected="selected"
                                value="0">0</option>
                                <option value="1">1</option>
                                <option value="2">2</option>
                                <option value="3">3</option>
                                <option value="4">4</option>
                                <option value="5">5</option>
                                <option value="6">6</option>
                                <option value="7">7</option>
                                <option value="8">8</option>
                                <option value="9">9</option>
                                <option value="10">10</option>
                            </select>
                            </div>
                            <div class="productPrice" id='price<%=currentItem%>'>
                                <%#"$" + Convert.ToDouble(Eval("Price")).ToString()%>
                            </div>
                        </li>
                    </ItemTemplate>
                </asp:ListView>
            </div>
            <div class="clearer">
                 </div>
            <div class="purchaseButton">
                <asp:Button ID="btnAddCart" runat="server" Text="Add to Cart" />
            </div>
        </div>

and my code behind:

    Dim counter As Int32
Public currentItem As Int32

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    'get all active products to display in the listing
    Dim query As String = "SELECT * FROM Products WHERE Active = 1"
    Dim dt As DataTable = DAL.Data.GetDataTable(query, "MainDB")
    counter = dt.Rows.Count
    lsvProducts.DataSource = dt
    lsvProducts.DataBind()
End Sub

Protected Sub btnAddCart_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnAddCart.Click
    'create a new instance of the cart
    Dim cart As New Core.Types.Cart

    'foreach item in the listing, find its details and add it to the shopping cart
    For I = 1 To counter
        Dim cartItem As New Core.Types.CartItem
        cartItem.Name = CType(productsContainer.FindControl("product" + I.ToString()), HtmlGenericControl).InnerText
        cartItem.Quantity = Convert.ToInt32(CType(productsContainer.FindControl("quantity" + I.ToString()), HtmlSelect).Value)
        cartItem.Price = Convert.ToDecimal(CType(productsContainer.FindControl("price" + I.ToString()), HtmlGenericControl).InnerText.Remove(0, 1))
        cartItem.ID = Convert.ToInt32(CType(productsContainer.FindControl("productID" + I.ToString()), HtmlGenericControl).InnerText)
        cart.AddItem(cartItem)
    Next

    If (cart.isEmpty) Then
        'empty cart, go nowhere. show a message saying the carts empty and to choose something.
    Else
        Response.Redirect("~/Checkout.aspx")
    End If
End Sub

Public Function setCurrent()
    currentItem = currentItem + 1
    Return currentItem
End Function

Please help... this is driving me insane!

Thanks in advance :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

走走停停 2024-08-15 15:08:12

如果您位于数据网格/中继器/列表视图中,要使用“FindControl”方法,您必须迭代列表视图中的数据项,然后对每个项目执行查找控制方法。例如,在 C# 中:

foreach(RepeaterItem item in Repeater1.Items)
{
    Literal lit = (Literal)item.FindControl("controlId");
}

我不确定这是否是确切的语法,但您明白我的意思。您不能只在 listview Id 上使用 find 控件方法 - 每个项目中服务器控件的 Id 都会被重写,因为您正在循环访问集合...

干杯,Sean

If you're in a datagrid/ repeater/ listview, to use the "FindControl" method, you'll have to iterate through the data items in the list view, then for each item peform the find control method. e.g. in C#:

foreach(RepeaterItem item in Repeater1.Items)
{
    Literal lit = (Literal)item.FindControl("controlId");
}

I'm not sure thats the exact syntax but you get what I mean. You can't just use the find control method on the listview Id - the Ids of server controls in each item get re-written because you're looping through a collection...

Cheers, Sean

栖迟 2024-08-15 15:08:12

FindControl 仅在当前命名容器中查找。如果您希望从不同的命名容器中查找控件,您应该有自己的(递归)实现。例如:

    private Control FindControlRecursive(Control parent, string id)
    {
        Control controlFound = parent.FindControl(id);
        int i = 0;
        while (controlFound == null && i < parent.Controls.Count)
        {
            controlFound = FindControlRecursive(parent.Controls[i++], id);
        }
        return controlFound;
    }

之后使用 FindControlRecursive(productsContainer, "product" + I.ToString())

FindControl only looks in the current naming container. If you wish to find controls from a different naming container, you should have your own (recursive) implementation. For example:

    private Control FindControlRecursive(Control parent, string id)
    {
        Control controlFound = parent.FindControl(id);
        int i = 0;
        while (controlFound == null && i < parent.Controls.Count)
        {
            controlFound = FindControlRecursive(parent.Controls[i++], id);
        }
        return controlFound;
    }

After that use FindControlRecursive(productsContainer, "product" + I.ToString())

眼中杀气 2024-08-15 15:08:12

看起来你的嵌套控件只是基本的 Html 控件?我不确定它们是否会在 ASP.NET 中注册,除非您使用 runat="server" 将它们注册为服务器端控件。

我已经有一段时间没有进行大量的 ASP.NET 开发了,但根据我之前的经验,我们总是使用服务器端控件并且没有任何问题。

It looks like your nested controls are just basic Html controls? I'm not sure they'll be registered with ASP.NET unless you have runat="server" to register them as server-side controls.

It's been a while since I've done heavy ASP.NET dev, but in my prior experience we always used server-side controls and had no problems.

笙痞 2024-08-15 15:08:12

我注意到的另一件事是,如果子页面的 ContentPlaceHolder 嵌套在母版页上 LoginView 内的 LoggedInTemplate 内,那么您可以忘记使用 FindControl 来获取子页面内控件的句柄。

The other thing I noticed was that if your ContentPlaceHolder for a child page is nested inside a LoggedInTemplate inside a LoginView on a masterpage, then you can forget about using FindControl to grab the handle on a control inside the child page.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文