Ashok Damani
Ashok Damani

Reputation: 127

Can't access the control in a listview

Can't access the control in a listview

error

Object reference not set to an instance of an object.

.cs

public void lnkaddtocart_Command(Object sender, CommandEventArgs e)
{
  ((TextBox)ListView_ProductDetails.FindControl("txtbox_pqty")).Visible = false;   
}

.aspx

<asp:ListView runat="server" ID="ListView_ProductDetails">
     <LayoutTemplate>
        <asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
     </LayoutTemplate>
     <ItemTemplate>
              <div class="qty">
                  Qty:
                  <asp:TextBox ID="txtbox_pqty" Text="1" runat="server"/>
                  <input type="hidden" name="product_id" size="2" value="41" />
                       <asp:LinkButton ID="lnkaddtocart" runat="server" 
                            CommandArgument='<%#Eval("pid") %>' 
                            OnCommand="lnkaddtocart_Command"  
                            cssclass="button">
                               <span>Add to Cart</span>
                        </asp:LinkButton>
                  </div>
    </ItemTemplate>
</asp:ListView>

Upvotes: 4

Views: 2911

Answers (5)

Mario S
Mario S

Reputation: 11945

You are using the textbox in an item template, so there will be multiple textboxes (one for each item). With that said, the Listview won't know which of these textboxes it should fetch.

You'd have to do a find for the textbox on the specific row where the linkbutton was clicked.

For example:

public void lnkaddtocart_Command(Object sender, CommandEventArgs e)
{
    var item = ((Control)sender).NamingContainer as ListViewItem;
    if (item != null)
    {
        ((TextBox)item.FindControl("txtbox_pqty")).Visible = false;
    }
}

Upvotes: 2

MMK
MMK

Reputation: 3721

Code Inline:

<asp:ListView runat="server" ID="ListView_ProductDetails" DataSourceID="SqlDataSource1"
            OnItemCommand="ListView_ProductDetails_ItemCommand">
            <LayoutTemplate>
                <asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
            </LayoutTemplate>
            <ItemTemplate>
                <div>
                    Qty:
                    <asp:TextBox ID="txtbox_pqty" Text="1" runat="server" />
                    <input type="hidden" name="product_id" size="2" value="41" />
                    <asp:LinkButton ID="lnkaddtocart" CommandName="addtocart" runat="server" CommandArgument='<%#Eval("pid") %>'
                        CssClass="button"><span>Add to Cart</span></asp:LinkButton>
                </div>
            </ItemTemplate>
 </asp:ListView>

Code Behind:

protected void ListView_ProductDetails_ItemCommand(object sender, ListViewCommandEventArgs e)
    {
        if (e.CommandName == "addtocart")
        {
            ((TextBox)e.Item.FindControl("txtbox_pqty")).Visible = false;
        }
    }

Hope this helps.

Upvotes: 1

ahaliav fox
ahaliav fox

Reputation: 2247

in addition to "Mario" add the event in your listview like this:

<asp:ListView runat="server" ID="ListView_ProductDetails" onitemcommand="lnkaddtocart_Command">
    <LayoutTemplate>
        <asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
    </LayoutTemplate>
    <ItemTemplate>
        <div class="qty">
            Qty:
            <asp:TextBox ID="txtbox_pqty" text='<%#Eval("pid") %>' runat="server" />
            <input type="hidden" name="product_id" size="2" value="41" />
            <asp:LinkButton ID="lnkaddtocart" runat="server" text='<%#Eval("pid") %>' CommandArgument='<%#Eval("pid") %>'
            cssclass="button"><span>Add to Cart</span></asp:LinkButton>
        </div>
    </ItemTemplate>
</asp:ListView>

CS:

public void lnkaddtocart_Command(object sender, ListViewCommandEventArgs e)
    {
        TextBox txt = (TextBox)e.Item.FindControl("txtbox_pqty");
        txt.Visible = false;
    }

Upvotes: 1

Paul Alan Taylor
Paul Alan Taylor

Reputation: 10680

The control you are looking for actually exists in repeated elements of ListView product details. To find the control, you'll need to traverse the control hierarchy.

Let's start here, in your method. First thing to do is get a reference to the ListViewItem that contains your button. In these .NET event signatures, sender refers to the control that raised the event.

public void lnkaddtocart_Command(Object sender, CommandEventArgs e)
{
    // Attempt to cast sender to a LinkButton
    LinkButton originator = sender as LinkButton;

    // Check that we've found it
    if ( originator != null )
    {
       // Now traverse the control hierarchy to get a ListViewItem
       var parentItem = originator.Parent as ListViewItem;

       if ( parentItem != null 
            && parentItem.ItemType == ListViewItemType.DataItem)
       {
          var textBox = parentItem.FindControl("txtbox_pqty") as TextBox;

          if ( textBox != null )
          {
             textBox.Visible = false;
          }
       }
    }
}

Upvotes: 0

Tim Schmelter
Tim Schmelter

Reputation: 460028

You need to use FindControl on the NamingContainer of the TextBox which is the ListViewItem and not the ListView. Therefore you can use the LinkButton's NamingContainer property to find the ListViewItem.

var ctrl = (Control) sender;
var lvi = (ListViewItem) ctrl.NamingContainer;
var txt = (TextBox)lvi.FindControl("txtbox_pqty");
txt.Visible = false; 

Upvotes: 2

Related Questions