2009-10-27 8 views
1

필자 이제 시간 동안 검색을 시도 페이지에 컨트롤을 찾을 수없는 이유는 내 코드를 찾을 수 없습니다 (일명, 저를.) 기본적으로FindControl 메서드는

실패 ... 내가이야리스트 뷰 제어 할 수 있습니다 제품의 데이터 테이블 (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 

도와주세요은 ...이 운전 나 미쳤어! 사전 :)에서

덕분에

답변

5

당신이 "의 FindControl"방법을 사용하려면 데이터 그리드/리피터/목록보기에 있다면, 당신은 다음에 대한 목록보기에서 데이터 항목을 반복해야합니다 각 항목은 찾기 제어 방법을 수행합니다. 예 : in C# :

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

정확한 구문이 맞는지는 모르겠지만 내 뜻을 알 수 있습니다. 당신이 컬렉션을 반복하고 있기 때문에 ... 재 작성 얻을 각 항목에

건배, 숀

5

의 FindControl을 IDS 서버 컨트롤의 - 당신은 목록보기 ID를 찾기 제어 방법을 사용할 수 없습니다 현재 명명 컨테이너에서만 찾습니다. 다른 이름 지정 컨테이너에서 컨트롤을 찾으려면 고유 한 (재귀 적) 구현이 있어야합니다. 예를 들면 :

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, "제품"+ I.ToString())

+0

+1. 코드를 보내 주셔서 감사합니다. – Jeremy

1

당신의 중첩 된 컨트롤은 단지 기본 HTML 컨트롤입니다처럼 보이는? 서버 측 컨트롤로 등록하기 위해 runat = "server"가 없으면 ASP.NET에 등록 될지 확신 할 수 없습니다.

무거운 ASP.NET 개발자가 된 이후로 오래되었지만 이전 경험에서 우리는 항상 서버 측 컨트롤을 사용하고 아무런 문제가 없었습니다.

0

내가 알아챈 또 다른 점은 자식 페이지의 ContentPlaceHolder가 MasterPage의 LoginView 안에있는 LoggedInTemplate 안에 중첩되어 있으면 FindControl을 사용하여 자식 페이지의 컨트롤에서 핸들을 가져 오는 것을 잊어 버릴 수 있다는 것입니다.