无法访问ListView中的控件

4

无法访问listview中的控件。

错误

对象引用未设置为对象的实例。

.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>
5个回答

2
您正在使用项目模板中的文本框,因此将会有多个文本框(每个项目一个)。因此,Listview 将不知道应该获取哪个文本框。
您需要在单击链接按钮的特定行上查找文本框。
例如:
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;
    }
}

OP 处理 LinkButtonItemCommand 事件而不是 ListView 的 ItemDataBound - Tim Schmelter
@TimSchmelter 您是正确的,尽管我只是想向 OP 展示 FindControlListView 中通常如何使用的示例,但我可以更改它以展示如何在 ItemCommand 中使用它。 - Mario S
我之所以提到这个,是因为这是两个完全不同的事件和两种不同的使用FindControl的方式(ItemDataBound已经被隐式地调用了每一个listviewitem,而RowCommand只针对那个LinkButton)。不需要 ;) - Tim Schmelter
@TimSchmelter 对不起,我应该更具体一些。我更新了代码示例,现在使用 NamingContainer - Mario S

2
你需要在TextBoxNamingContainer上使用FindControl,该NamingContainerListViewItem而不是ListView。因此,你可以使用LinkButtonNamingContainer属性来查找ListViewItem
var ctrl = (Control) sender;
var lvi = (ListViewItem) ctrl.NamingContainer;
var txt = (TextBox)lvi.FindControl("txtbox_pqty");
txt.Visible = false; 

1

除了"Mario"之外,像这样在您的列表视图中添加事件:

<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;
    }

1

代码内联:

<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>

代码后台:

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

希望这能有所帮助。

0

您要查找的控件实际上存在于ListView产品详细信息的重复元素中。要找到该控件,您需要遍历控件层次结构。

让我们从这里开始,在您的方法中。首先要做的是获取包含按钮的ListViewItem的引用。在这些.NET事件签名中,sender指的是引发事件的控件。

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;
          }
       }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接