占位符在Repeater中

时间:2013-11-12 14:41:34

标签: c# asp.net repeater

我有一个转发器,里面有一个占位符,它应该根据来自数据库的内容加载不同的控件。但是,它在页面加载时会下降,我看不出原因。

  

异常详细信息:System.NullReferenceException:未将对象引用设置为对象的实例。

代码是:

protected void rptTabs_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    DataRowView nRow = null;

    switch (e.Item.ItemType)
    {
        case ListItemType.Item:
        case ListItemType.AlternatingItem:
            nRow = (DataRowView)e.Item.DataItem;
            String NavURL = "" + nRow["ProdTab"];
            NavURL = NavURL.Replace(" ", "");
            NavURL = NavURL.Replace("+", "");
            ((HyperLink)e.Item.FindControl("lnkTabs")).Text = "" + nRow["ProdTab"];
            ((HyperLink)e.Item.FindControl("lnkTabs")).NavigateUrl = "#" + NavURL;
            PlaceHolder PlaceHolder1 = (PlaceHolder)e.Item.FindControl("PlaceHolder1");
            switch (NavURL)
            {
                case "Fire":
                    var uc = LoadControl("~/controls/Fire.ascx");
                    PlaceHolder1.Controls.Add(uc); 
                    break;
            }
            break;
    }
}

该行的错误:

PlaceHolder1.Controls.Add(uc); 

HTML是:

 <asp:Repeater runat="server" id="rptSecondTab" 
               OnItemDataBound="rptSecondTab_ItemDataBound">
     <ItemTemplate>
         <div id="divIcon" ClientIDMode="Static" runat="server" class="tab-pane 
                           overflow-auto">
             <asp:PlaceHolder runat="server" ID="PlaceHolder1"></asp:PlaceHolder>
         </div>
     </ItemTemplate>
 </asp:Repeater>

修改:更多信息:

Source Error: 


Line 81:                         case "Fire":
Line 82:                             var uc = LoadControl("~/controls/Fire.ascx");
Line 83:                             PlaceHolder1.Controls.Add(uc);
Line 84:                             break;
Line 85:                     }

Source File: c:\Development\PIDs\PIDs\PIDs\SubPID.aspx.cs    Line: 83 

Stack Trace: 


[NullReferenceException: Object reference not set to an instance of an object.]
   PIDs.SubPID.rptTabs_ItemDataBound(Object sender, RepeaterItemEventArgs e) in c:\Development\PIDs\PIDs\PIDs\SubPID.aspx.cs:83
   System.Web.UI.WebControls.Repeater.OnItemDataBound(RepeaterItemEventArgs e) +111
   System.Web.UI.WebControls.Repeater.CreateItem(Int32 itemIndex, ListItemType itemType, Boolean dataBind, Object dataItem) +138
   System.Web.UI.WebControls.Repeater.CreateControlHierarchy(Boolean useDataSource) +9546651
   System.Web.UI.WebControls.Repeater.OnDataBinding(EventArgs e) +61
   System.Web.UI.WebControls.Repeater.DataBind() +105
   PIDs.SubPID.Setup_Tabs(String Tabs) in c:\Development\PIDs\PIDs\PIDs\SubPID.aspx.cs:61
   PIDs.SubPID.Setup_SPID() in c:\Development\PIDs\PIDs\PIDs\SubPID.aspx.cs:51
   PIDs.SubPID.Page_Load(Object sender, EventArgs e) in c:\Development\PIDs\PIDs\PIDs\SubPID.aspx.cs:29
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +51
   System.Web.UI.Control.OnLoad(EventArgs e) +92
   System.Web.UI.Control.LoadRecursive() +54
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +772

1 个答案:

答案 0 :(得分:0)

我相信你遇到了开箱即用.FindControl()方法的限制,它不会在自己的命名容器中寻找控件。换句话说,.FindControl()不会递归地将控制层次结构降级为子项,孙子项等。

请尝试使用此递归版本:

public static class ControlExtensions
{
    public static Control FindControlRecursive(this Control theControl,
                                               string theControlId)
    {
        if (theControl == null)
        {
            return null;
        }

        // Try to find the control at the current level
        var theControlToBeFound = theControl.FindControl(theControlId);

        if (theControlToBeFound == null)
        {
            // Search the children
            foreach (Control theChildControl in theControl.Controls)
            {
                theControlToBeFound = FindControlRecursive(theChildControl,
                                                           theControlId);

                if (theControlToBeFound != null)
                {
                    break;
                }
            }
        }

        return theControlToBeFound;
    }
}

用法:

var PlaceHolder1 = e.Item.FindControlRecursive("PlaceHolder1") as PlaceHolder;