2012-07-11 56 views
2

我正在處理用戶表單,我希望根據用戶需要(在按鈕單擊事件上)動態生成儘可能多的輔助手機字段。我已經按照此頁面上Daniel的動態控制實例:How can I re-instantiate dynamic ASP.NET user controls without using a database?動態ascx用戶控件的空引用異常

我也實現了這個網頁上提出lordscarlet「事件冒泡」的解決方案:Eventhandling in ascx usercontrols

我user.aspx頁面的相關部分:

<asp:Panel ID="phonePnl" runat="server"></asp:Panel> 
      <tr><td><asp:Button ID="phoneBtn" Text="Add Secondary Phone" OnClick="phoneBtn_Click" runat="server" /></td></tr> 

user.aspx.cs的相關部分代碼隱藏

// ============================================================================ 
protected void phoneBtn_Click(object sender, EventArgs e) 
{ 
    UserControl controlToAdd = new UserControl(); 
    controlToAdd = (UserControl)controlToAdd.LoadControl("~/DynamicData/FieldTemplates/SecondaryPhone.ascx"); 

    controlToAdd.ID = Guid.NewGuid().ToString(); 

    Panel phonePnl = (Panel)fvUser.FindControl("phonePnl"); 

    Literal lit = new Literal(); 
    lit.Text = "<tr><td>Secondary Phone</td><td>"; 
    phonePnl.Controls.Add(lit); 
    phonePnl.Controls.Add(controlToAdd); 
    lit = new Literal(); 
    lit.Text = "</td></tr>"; 
    phonePnl.Controls.Add(lit); 

    myControlList.Add(controlToAdd.ID, controlToAdd.AppRelativeVirtualPath); 
    Session["myControlList"] = myControlList; 
} 

// ============================================================================ 
protected override void OnInit(EventArgs e) 
{ 
    InitializeComponent(); 
    if (!IsPostBack) 
    { 
     myControlList = new Dictionary<string, string>(); 
     Session["myControlList"] = myControlList; 
    } 
    else 
    { 
     myControlList = (Dictionary<string, string>)Session["myControlList"]; 

     foreach (var registeredControlId in myControlList.Keys) 
     { 
      UserControl controlToAdd = new UserControl(); 
      controlToAdd = (UserControl)controlToAdd.LoadControl(myControlList[registeredControlId]); 
      Panel phonePnl = new Panel(); 
      phonePnl = (Panel)fvUser.FindControl("phonePnl"); 
      phonePnl.Controls.Add(controlToAdd); 
     } 
    } 
    base.OnInit(e); 
} 

// ============================================================================ 
private void InitializeComponent() 
{ 
    this.Load += new System.EventHandler(this.Page_Load); 
    SecondaryPhoneControl.BubbleClick += new EventHandler(admin_user_BubbleClick); 
} 

// ============================================================================ 
private void admin_user_BubbleClick(object sender, EventArgs e) 
{ 
    //todo 
} 

請注意,我添加了最後一行:
Session [「myControlList」] = myControlList;

另外,fvUser只是我在user.aspx頁面中的FormView ID。

雖然這不是Daniel的解決方案,但我的想法是,對於您添加的每個控件,都需要將其添加到您的Dictionary中。我完全誤導了嗎?

我的用戶控件是帶有TextBox和Button的ascx(用於刪除控件,如果用戶決定不需要該字段)。請注意,此刪除操作尚未實現,但在解決此問題後,該事件在我的父代碼中。

SecondaryPhone.ascx

<%@ Control Language="C#" CodeBehind="SecondaryPhone.ascx.cs" Inherits="TwentyFourSeven.DynamicData.FieldTemplates.SecondaryPhone" %> 

SecondaryPhone.ascx.cs

using System; 
using System.Data; 
using System.Configuration; 
using System.Collections; 
using System.Collections.Specialized; 
using System.Linq; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using System.Web.UI.HtmlControls; 
using System.Xml.Linq; 
using System.Web.DynamicData; 

namespace TwentyFourSeven.DynamicData.FieldTemplates 

{ 
public partial class SecondaryPhone : System.Web.UI.UserControl 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 

    } 

    public void SetPhone(String phone) 
    { 
     secPhoneTxt.Text = phone; 
    } 

    protected override void LoadViewState(object savedState) 
    { 
     base.LoadViewState(savedState); 
     secPhoneTxt.Text = (String)ViewState["secPhoneTxt"]; 
    } 

    protected override object SaveViewState() 
    { 
     ViewState["secPhoneTxt"] = secPhoneTxt.Text; 
     return base.SaveViewState(); 
    } 

    private void secPhoneBtn_Click(object sender, EventArgs e) 
    { 
    } 

    public event EventHandler BubbleClick; 

    protected void OnBubbleClick(EventArgs e) 
    { 
     if (BubbleClick != null) 
     { 
      BubbleClick(this, e); 
     } 
    } 

    protected override void OnInit(EventArgs e) 
    { 
     InitializeComponent(); 
     base.OnInit(e); 
    } 

    private void InitializeComponent() 
    { 
     this.secPhoneBtn.Click += new System.EventHandler(this.secPhoneBtn_Click); 
     this.Load += new System.EventHandler(this.Page_Load); 
    } 
} 
} 

調試時,第一次加載頁面時OnInit的正常運行,並且點擊添加輔助電話按鈕在fi上工作首先點擊。第二次點擊拋出一個空引用異常(對象引用不設置爲一個對象的一個​​實例)在此行我的OnInit方法的:

phonePnl.Controls.Add(controlToAdd); 

在調試我注意到,在按鈕的第一次點擊,在我phoneBtn_Click方法,controlToAdd.Application,controlToAdd.Cache等也會拋出空引用異常,但它仍然生成控件並返回頁面。它還將控件及其ID添加到詞典中。

然後在按鈕的第二次單擊之前,就在它遇到導致異常的行之前,我的phonePnl變量爲空。我可以推測這是導致異常的原因,但爲什麼我的phonePnl變量在這種情況下爲空,而不是在第二次OnInit調用/第一次回發中?

我一直對這一切感慨萬分,我希望有人能提供一些見解。

回答

0

,而不是controlToAdd.LoadControl使用Page.LoadControl,看看是否能工程

+0

同樣發生異常 - 有引用頁LoadControl,而不是特定的控制的LoadControl有區別嗎? – AWollan 2012-07-11 17:02:45