【问题标题】:ASP.NET - child control in a Repeater doesn't get initialized in timeASP.NET - 中继器中的子控件未及时初始化
【发布时间】:2014-04-10 16:11:24
【问题描述】:

我面临以下问题:我有一个 asp 中继器,它有一个控件作为 ItemTemplate。在代码隐藏中,我为转发器分配了一个数据源:

...
this.ProductList = searchResult.Entry.ToList();
EntriesList.DataSource = this.ProductList;
...


void EntriesList_ItemDataBound(object sender, ListViewItemEventArgs e)
{
    var productBlock = (ProductBlock)e.Item.FindControl("productBlock"); //Here I obtain the child, then assign the values from the datasource
    productBlock.ProductEntry = (Entry)e.Item.DataItem;
}

这是子控件的aspx代码:

<%@ Control Language="C#" CodeBehind="ProductBlock.ascx.cs" Inherits="EPiServer.Commerce.Sample.Templates.Sample.Units.CategoryDisplay.SharedModules.ProductBlock" %>
<%@ Import Namespace="EPiServer.Commerce.Sample" %>
<%@ Import Namespace="EPiServer.Commerce.Catalog.ContentTypes" %>
<%@ Import Namespace="EPiServer.Core.Html" %>
<%@ Import Namespace="EPiServer.Commerce.Catalog.ContentTypes" %>
<%@ Import Namespace="Mediachase.Commerce.Catalog.Objects" %>
<%@ Import Namespace="Mediachase.Commerce.Website.Helpers" %>
<%@ Register Src="StarButton.ascx" TagName="StarButton" TagPrefix="catalog" %>
<%@ Register Src="CommonButtons.ascx" TagName="CommonButtons" TagPrefix="catalog" %>

<li class="span3">
    <div class="thumbnail thumbnail-product">
        <catalog:StarButton runat="server" ID="StarButton" />
        <asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl='<%# ResolveUrl(StoreHelper.GetEntryUrl(ProductEntry)) %>'>
            <span class="product-img-holder">

                <asp:Image runat="server" ID="Image1" AlternateText="" />
            </span>
        </asp:HyperLink>
        <div class="product-dsc">
            <asp:HyperLink ID="HyperLink3" runat="server" NavigateUrl='<%# ResolveUrl(StoreHelper.GetEntryUrl(ProductEntry)) %>'  CssClass="product-name">
                <span><asp:Literal ID="HeadingLiteral" runat="server" /></span>
            </asp:HyperLink>
            <div class="tp-additional">
                <ul class="unstyled">
                    <li><strong>Marca:</strong>
                        <asp:Literal ID="BrandLiteral" runat="server" />
                    </li>
                    <li>
                        <strong>Principio Activo:</strong>
                        <asp:Literal ID="ActiveIngredientLiteral" runat="server" />
                    </li>
                    <li>
                        <strong>Patología:</strong>
                        <asp:Literal ID="PathologyLiteral" runat="server" />
                    </li>
                    <%--<li><strong>In Stock:</strong> <asp:Literal ID="InStock" runat="server"></asp:Literal></li>--%>
                    <li><strong>Código Nacional:</strong>
                        <span title="<%# ProductEntry.ID %>"><%# ProductEntry.ID %></span></li>
                    <%--<li><strong>Model:</strong>
                        <%# WebStringHelper.EncodeForWebString(GetModelNumber((EntryContentBase) Container.DataItem)) %></li>
                    <li><strong>List Price:</strong> <asp:Literal ID="ListPrice" runat="server" /></li>
                    <li><strong>Discount Pricing</strong> <asp:Literal ID="DiscountPricing" runat="server" /></li>
                    <li><strong>You Save:</strong> <asp:Literal ID="DiscountAmount" runat="server" /></li>--%>
                </ul>                              
                <asp:PlaceHolder runat="server" Visible="False" ID="PromotionsHolder">
                    <%--<strong>Promotions:</strong><br />
                    <asp:Literal ID="Promotions" runat="server" />--%>                         
                </asp:PlaceHolder>
            </div>
            <div class="C_Product-ItemSelector">
                <div class="btn-group">
                    <a class="btn btn-info" href="<%# ResolveUrl(StoreHelper.GetEntryUrl(ProductEntry)) %>"><i class="icon-shopping-cart icon-white"></i> Ver detalles</a> 
                    <a class="btn btn-info dropdown-toggle" data-toggle="dropdown" href="#"><span class="caret"></span></a>
                    <catalog:CommonButtons runat="server" ID="CommonButtons" />
                </div>
            </div>
        </div>
    </div>
</li>

此控件背后的代码只是设置应赋予 ProductEntry 公共属性的值。在调试中,执行 EntriesList.DataSource = this.ProductList; 后立即行,应用程序引发 NullArgumentException,告诉我子控件的 ProductEntry 属性为空。

但是,如果在中继器的子控件后面的代码中,我会执行以下操作:

    protected void Page_Init(object sender, EventArgs e)
    {
        ProductEntry = new Entry();
    }

一切正常,因为 ProductEntry 将不再为空。

这个解决方案对我来说相当难看,我不知道它为什么会发生,以及在中继器内为子控件设置值的最佳方法是什么。谁能赐教?

谢谢

【问题讨论】:

    标签: asp.net webforms repeater


    【解决方案1】:

    你说的是中继器控制。如果是这样,EntriesList_ItemDataBound 的 EventArgs 应该是 RepeaterItemEventArgs

    另一个问题是你需要在ItemDataBound中过滤ItemType,因为Header、Footer等也会触发ItemDataBound事件。

    protected void EntriesList_ItemDataBound(
       Object Sender, RepeaterItemEventArgs e) {
    
       if (e.Item.ItemType == ListItemType.Item || 
          e.Item.ItemType == ListItemType.AlternatingItem) {
    
          var productBlock = (ProductBlock)e.Item.FindControl("productBlock"); 
          productBlock.ProductEntry = (Entry)e.Item.DataItem;          
       }
    } 
    

    【讨论】:

      【解决方案2】:

      Win 你的方法不起作用,在我可以分配它们的值之前,子对象仍在创建和初始化。

      希望我找到了解决方案。使用 OnItemCreated 事件而不是 OnItemDatabound 事件解决了我的问题,因为它是在创建子项时调用的,但在调用子项的 Page_Init 事件之前。

      谢谢

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-27
        相关资源
        最近更新 更多