2010-06-30 132 views
0

我正在構建一個自定義控件庫。我的控件是從CompositeControl繼承的。 根據用戶的回答,我必須插入更多的自定義控件。我有一個從客戶端代碼傳入的PlaceHolder(_ph)。我將我的控件插入該PlaceHolder。ASP自定義控件不會觸發正確的事件

我的問題是我在事件處理程序中插入的控件不會觸發它的事件,但會觸發父事件。例如,如果我有一個EddDropDown A,並且用戶選擇了一個答案,那麼我必須在edd_SelectedIndexChanged中創建EddDropDown B和C.當我爲B選擇一個答案時,它觸發A而不是B的SelectedIndexChanged。

我認爲它與進入頁面循環遲到有關。我不知道如何解決它。請幫忙。真的很感謝任何助理。 在此先感謝。

這是我的控制的一個例子:使用System.Collections.Generic

using System; 

;使用System.Collections的 ;

using System.Linq; using System.Text; using System.ComponentModel; using System.Security.Permissions; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; 使用CommerceBank.DueDiligence.ServiceProxies.Internal.Edd; using System.Collections.Specialized; using System.Runtime.Serialization;

命名空間CommerceBank.DueDiligence.ClientFacade.WebForms { 公共類EddDropDownListArgs:EventArgs的 { 私人詮釋_iQuestionID; string _sAnswer = string.Empty; 私人DueDiligenceProfile _customerProfile;

public EddDropDownListArgs(int iQuestionID, string sAnswer,DueDiligenceProfile customer) 
    { 
     _iQuestionID = iQuestionID; 
     _sAnswer = sAnswer; 
     _customerProfile = customer; 
    } 
    public int QuestionID 
    { 
     get 
     { 
      return _iQuestionID; 
     } 
     set 
     { 
      _iQuestionID = value; 
     } 
    } 
    public string Answer 
    { 
     get 
     { 
      return _sAnswer; 
     } 
     set 
     { 
      _sAnswer = value; 
     } 
    } 
    public DueDiligenceProfile customerProfile 
    { 
     get 
     { 
      return _customerProfile; 
     } 
     set 
     { 
      _customerProfile = value; 
     } 
    } 

} 
public delegate void EddDropDownSelectedIndexChangedHandler(object sender, EddDropDownListArgs ce); 



[ 
AspNetHostingPermission(SecurityAction.Demand, 
    Level = AspNetHostingPermissionLevel.Minimal), 
AspNetHostingPermission(SecurityAction.InheritanceDemand, 
    Level = AspNetHostingPermissionLevel.Minimal), 
DefaultProperty("ID"), 
ToolboxData("<{0}:EddDropDown runat=\"server\"> </{0}:EddDropDown>"), 
Serializable 
] 
public class EddDropDown : CompositeControl, IChannelControl,ISerializable, IPostBackEventHandler, IPostBackDataHandler 
{ 
    [Serializable] 
    struct EddDropDownData 
    { 
     public int _iQuestionID; 
     public String _sQuestion; 
     //public AnswerOption[] _PossibleAnswers; 
     public String _sAnswer; 
     //public DueDiligenceProfile _customerProfile; 
    } 

    [ 
    Bindable(true), 
    Category("Appearance"), 
    DefaultValue(""), 
    Description("This is EddCheckBox"), 
    Localizable(true) 
    ] 
    private int _iQuestionID=-1; 
    private String _sQuestion = string.Empty; 
    private AnswerOption[] _PossibleAnswers; 
    private String _sAnswer = string.Empty; 
    private DueDiligenceProfile _customerProfile; 
    private EddDropDownData _data = new EddDropDownData(); 
    Label _lQuestion = null; 
    DropDownList _ddl = null; 

    #region implement custom events 
    public event EddDropDownSelectedIndexChangedHandler SelectedIndexChanged; 
    protected virtual void OnSelectedIndexChanged(EddDropDownListArgs eddEvent) 
    { 
     if (SelectedIndexChanged != null) 
     { 
      System.Diagnostics.Trace.WriteLine("OnSelectedIndexChanged. QuestionID:" 
       + eddEvent.QuestionID 
       + " Answer: " 
       + eddEvent.Answer); 
      SelectedIndexChanged(this, eddEvent); 
     } 
    } 
    #endregion 

    #region IPostBackEventHandler_implementation 
    // Define the method of IPostBackEventHandler that raises change events. 
    void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) 
    { 
     System.Diagnostics.Trace.WriteLine("in RaisePostBackEvent" + eventArgument); 
     OnSelectedIndexChanged(new EddDropDownListArgs(EDDQuestionID(), EDDAnswerValue(), _customerProfile)); 
    } 
    #endregion 

    #region IPostBackDataHandler_implementation 
    bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection) 
    { 
     //System.Diagnostics.Trace.WriteLine("in LoadPostData"); 

     //int i = int.Parse(postCollection["SelectedIndex"]); 
     //string s = postCollection["SelectedValue"]; 

     //if (SelectedIndex >= 0) 
     // Page.RegisterRequiresRaiseEvent(this); 
     //return false; 
     return true; 
    } 
    void IPostBackDataHandler.RaisePostDataChangedEvent() 
    { 
     System.Diagnostics.Trace.WriteLine("in RaisePostDataChangedEvent"); 
    } 
    #endregion 

    #region ISerializable_implementation 
    [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] 
    public void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     info.AddValue("ControlType", GetType().Name); 
     info.AddValue("ControlID", ID); 
     info.AddValue("QuestionID", _iQuestionID); 
     info.AddValue("Question", Question); 
     info.AddValue("Answer", EDDAnswerValue()); 
     info.AddValue("PossibleAnswerCount", _PossibleAnswers.Length); 
     for (int i=0; i < _PossibleAnswers.Length; i++) 
     { 
      info.AddValue("a" + i.ToString(), _PossibleAnswers[i]); 
     } 
    } 
    #endregion 


    #region IChannel_implementation 
    public int EDDQuestionID() 
    { 
     return QuestionID; 
    } 
    public string EDDAnswerValue() 
    { 
     EnsureChildControls(); 
     for (int i = 0; i < Controls.Count; i++) 
     { 
      if (Controls[i].ID == "ans" + QuestionID) 
      { 
       _sAnswer = ((DropDownList)Controls[i]).SelectedValue; 
       _data._sAnswer = ((DropDownList)Controls[i]).SelectedValue; 
       ViewState["SelectedIndex"] = ((DropDownList)Controls[i]).SelectedIndex; 

       return ((DropDownList)Controls[i]).SelectedValue; 
      } 
     } 
     return null; 
    } 
    #endregion 

    #region Overriden properties 
    public override ControlCollection Controls 
    { 
     get 
     { 
      EnsureChildControls(); 
      return base.Controls; 
     } 
    } 
    #endregion 

    #region Properties 
    public int QuestionID 
    { 
     get 
     { 
      _iQuestionID = (int)ViewState["QuestionID"]; 
      return _iQuestionID; 
     } 
     set 
     { 
      ViewState["QuestionID"] = value; 
      _iQuestionID = value; 
     } 
    } 
    public string Question 
    { 
     get 
     { 
      _sQuestion = (string)ViewState["Question"]; 
      return _sQuestion; 
     } 
     set 
     { 
      ViewState["Question"] = value; 
      _sQuestion = value; 
     } 
    } 
    public string Answer 
    { 
     get 
     { 
      return _sAnswer; 
     } 
     set 
     { 
      _sAnswer = value; 
     } 
    } 
    public int SelectedIndex 
    { 
     get { 
      EnsureChildControls(); 
      if (ViewState["SelectedIndex"] != null) 
       _ddl.SelectedIndex = (int)ViewState["SelectedIndex"]; 
      else 
       _ddl.SelectedIndex = 0; 
      return _ddl.SelectedIndex; 
     } 
     set { 
      EnsureChildControls(); 
      ViewState["SelectedIndex"] = value; 
      _ddl.SelectedIndex = value; 
     } 
    } 
    public string SelectedValue 
    { 
     get 
     { 
      EnsureChildControls(); 
      _ddl.SelectedValue =(string)ViewState["SelectedValue"]; 
      return _ddl.SelectedValue; 
     } 
     set 
     { 
      EnsureChildControls(); 
      ViewState["SelectedValue"] = value; 
      _ddl.SelectedValue = value; 
     } 
    } 
    #endregion 


    public EddDropDown(int iQuestionID 
     , string sQuestion 
     , DueDiligenceProfile cust 
     , AnswerOption[] sPossibleAnswers 
     ) 
    { 
     System.Diagnostics.Trace.WriteLine("Add EddDropDown. QuestionID :" 
              + iQuestionID.ToString() 
              + sQuestion); 
     QuestionID = iQuestionID; 
     Question = sQuestion; 

     _data._iQuestionID = iQuestionID; 
     _data._sQuestion = sQuestion; 

     _PossibleAnswers = sPossibleAnswers; 
     _customerProfile = cust; 
     ID = iQuestionID.ToString()+GetCustomerID(); 


    } 

    public EddDropDown(SerializationInfo info, StreamingContext context) 
    { 
     string sControlType = info.GetString("ControlType"); 
     ID = info.GetString("ControlID"); 
     QuestionID = info.GetInt32("QuestionID"); 
     Question = info.GetString("Question"); 
     string sAnswer = info.GetString("Answer"); 

     int iAnswerCount = info.GetInt32("PossibleAnswerCount"); 
     List<AnswerOption> answerOptions = new List<AnswerOption>(); 
     for (int i = 0; i < iAnswerCount; i++) 
     { 
      Type t = typeof(AnswerOption); 
      AnswerOption ao = (AnswerOption)info.GetValue("a" + i.ToString(), t); 
      answerOptions.Add(ao); 
     } 

     _PossibleAnswers = answerOptions.ToArray(); 
    } 
    protected override object SaveViewState() 
    { 
     ViewState["SelectedIndex"] = _ddl.SelectedIndex; 

     return base.SaveViewState(); 
    } 

    protected override void LoadViewState(object savedState) 
    { 
     //if (ViewState["SelectedIndex"] != null) 
     // _ddl.SelectedIndex = (int)ViewState["SelectedIndex"]; 
     //else 
     // _ddl.SelectedIndex = 0; 
     if (savedState != null) 
     { 
      Pair mystate = (Pair)savedState; 
      ArrayList al =(ArrayList)mystate.First; 
      for (int i = 0; i < al.Count;i++) 
      { 
       if (al[i].GetType().Name == "IndexedString") 
       { 
        if (((IndexedString)al[i]).Value == "SelectedIndex") 
        { 
         ViewState["SelectedIndex"] = al[i + 1].ToString(); 
         System.Diagnostics.Trace.WriteLine(al[i + 1].ToString()); 
        } 
       } 
      } 



     } 
     base.LoadViewState(savedState); 
    } 
    //need this to get the post back 
    protected override void AddAttributesToRender(HtmlTextWriter writer) 
    { 
     writer.AddAttribute(HtmlTextWriterAttribute.Name, this.ID); 
     writer.AddAttribute(HtmlTextWriterAttribute.Onchange, 
      Page.ClientScript.GetPostBackEventReference(this, ID)); 
     //writer.AddAttribute(HtmlTextWriterAttribute.Onchange, 
     // Page.ClientScript.GetPostBackEventReference(_ddl, _ddl.ID)); 
     base.AddAttributesToRender(writer); 
    } 

    protected override void OnPreRender(EventArgs e) 
    { 
     base.OnPreRender(e); 
     Page.RegisterRequiresPostBack(this);//must register postback in OnPreRender 
    } 
    protected override void Render(HtmlTextWriter writer) 
    { 
     //Ensures that this control is nested in a server form 
     if (Page != null) 
     { 
      Page.VerifyRenderingInServerForm(this); 
     } 
     base.Render(writer); 
    } 
    protected override void RenderContents(HtmlTextWriter writer) 
    { 
     RenderChildren(writer); 
    } 

    protected override void CreateChildControls() 
    { 
     Controls.Clear(); 

     _lQuestion = new Label(); 
     _lQuestion.ID = "quest" + QuestionID; 
     _lQuestion.Text = Question; 
     _ddl = new DropDownList(); 
     _ddl.ID = "ans" + QuestionID; 

     //add "select one" 
     ListItem liSelectOne = new ListItem("Please select one"); 
     _ddl.Items.Add(liSelectOne); 
     for (int i = 0; i < _PossibleAnswers.Count(); i++) 
     { 
      AnswerOption a = _PossibleAnswers[i]; 

      ListItem li = new ListItem(a.Value.ToString()); 
      _ddl.Items.Add(li); 
      //if (a.ChildQuestions == null)//default it to the answer that don't have some children 
      // ddl.Items[i].Selected = true; 
     } 
     if (_sAnswer != string.Empty) 
      _ddl.SelectedValue = _sAnswer; 


     _ddl.AutoPostBack = true;//must have 
     _ddl.SelectedIndexChanged += new EventHandler(ddl_SelectedIndexChanged); 
     if (ViewState["SelectedIndex"] != null) 
      _ddl.SelectedIndex = (int)ViewState["SelectedIndex"]; 
     //else 
     // _ddl.SelectedIndex = 0; 

     Page.RegisterRequiresPostBack(_ddl); 
     Page.RegisterRequiresControlState(_ddl); 

     Controls.Add(new LiteralControl("<br>")); 
     Controls.Add(_lQuestion); 
     Controls.Add(new LiteralControl("<br>")); 
     Controls.Add(_ddl); 

     ChildControlsCreated = true; 
     //ClearChildViewState(); 
    } 
    private string GetCustomerID() 
    { 
     if (_customerProfile.Customer.PermanentId >0) 
      return _customerProfile.Customer.PermanentId.ToString(); 
     else if (_customerProfile.Customer.RcifId != null && _customerProfile.Customer.RcifId != "") 
      return _customerProfile.Customer.RcifId; 
     else 
      return _customerProfile.Customer.TaxId.ToString(); 
    } 
    //to do: delete 
    //void edd_SelectedIndexChanged(object sender, EddDropDownListArgs ea) 
    //{ 
    // System.Diagnostics.Trace.WriteLine("get here"); 
    //} 
    void ddl_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     Control c = (Control)sender; 
     System.Diagnostics.Trace.WriteLine("ddl_SelectedIndexChanged " 
      + c.GetType().Name); 
     OnSelectedIndexChanged(new EddDropDownListArgs(EDDQuestionID(), EDDAnswerValue(),_customerProfile)); 
    } 
    protected override void RenderChildren(HtmlTextWriter output) 
    { 
     if (HasControls()) 
     { 
      for (int i = 0; i < Controls.Count; i++) 
      { 
       Controls[i].RenderControl(output); 
      } 
     } 

    } 



} 

}

這是創建控件的代碼:

 public EddDropDown GetDropDown(DueDiligenceProfile cust, Question quest) 
    { 

     Control c = null; 
     if (HasControl(quest.Id.ToString(), "EddDropDown", ref c)) 
      return (EddDropDown)c; 
     string sQuestion = null; 

     AnswerOption[] sPossAnswers; 
     sPossAnswers = FindPossibleAnswers(cust.Questions, quest.Id, ref sQuestion); 
     if (sPossAnswers == null) 
      throw (new Exception("failed to get possible answers")); 
     EddDropDown edd = new EddDropDown(quest.Id, 
          sQuestion, 
          cust, 
          sPossAnswers 
          ); 
     edd.ID = quest.Id.ToString(); 
     edd.SelectedIndexChanged += new EddDropDownSelectedIndexChangedHandler(edd_SelectedIndexChanged); 
     _data._EDDControls.Add(edd); 
     int iParentQuestionID = FindParentQuestionID(cust.Questions, quest.Id, ref sQuestion); 
     int iControlIdx = GetIndexOf(iParentQuestionID, _ph.Controls); 
     if (iControlIdx >-1) 
      _ph.Controls.AddAt(iControlIdx + 1, edd); 
     else 
      _ph.Controls.Add(edd); 
     //build children questions if they have result 
     if (quest.Results.Length >0) 
     { 

      foreach (Result r in quest.Results) 
      { 
       edd.SelectedValue = r.Value; 
       foreach (AnswerOption ao in quest.AnswerOptions) 
       { 
        if (r.Value == ao.Value) 
        { 
         if (ao.ChildQuestions == null) 
          continue; 
         foreach (Question q in ao.ChildQuestions) 
         { 
          EddDropDown e = GetDropDown(cust, q); 
          e.BackColor = System.Drawing.Color.CadetBlue; 
         } 
        } 
       } 
      } 
     } 
     return edd; 

    } 
    void edd_SelectedIndexChanged(object sender, EddDropDownListArgs ea) 
    { 
     System.Diagnostics.Trace.WriteLine("EddQuestionare--edd_SelectedIndexChanged. QuestionID:" 
        + ea.QuestionID 
        + " Answer: " 
        + ea.Answer); 

     //Control parentControl = null; 
     //if (sender.GetType().Name == "EddDropDown") 
     //{ 
     // parentControl = (Control)sender; 

     //} 
     //Control c = (Control)sender; 

     //while (c.GetType().Name != "PlaceHolder") 
     // c = c.Parent; 

     string sQuestion = null; 

     AnswerOption[] ansOptions = FindPossibleAnswers(ea.customerProfile.Questions 
           , ea.QuestionID 
           , ref sQuestion); 

     foreach (AnswerOption ao in ansOptions) 
     { 
      if (ao.Value == ea.Answer)//found answer 
      { 
       if (ao.ChildQuestions == null) 
        break; 

       //create sub questions 
       for (int i = 0; i < ao.ChildQuestions.Length; i++)//and there are subquestions 
       { 
        _ph.Controls.Add(new LiteralControl("&nbsp;&nbsp;&nbsp;&nbsp;")); 
        if (ao.ChildQuestions[i].AnswerOptions.Length > 2) 
        { 
         EddDropDown subQues = GetDropDown(ea.customerProfile 
              , ao.ChildQuestions[i]); 
         subQues.BackColor = System.Drawing.Color.Aqua; 
        } 
        else if (ao.ChildQuestions[i].AnswerOptions.Length == 2) 
        { 
         EddRadioButtonList erb = GetRadioButtonList(ea.customerProfile 
              , ao.ChildQuestions[i].Id); 
         erb.BackColor = System.Drawing.Color.BlueViolet; 
        } 
        else 
        { 
         EddTextArea eta = GetTextArea(ea.customerProfile 
              , ao.ChildQuestions[i].Id); 
         eta.BackColor = System.Drawing.Color.Bisque; 
        } 
       } 
       break; 
      } 
     } 
     //DisplayControls(); 
     //Serialize(); 
    } 

有,我還沒有清理出來的幾件事情,但你的想法。

回答

0

回發事件可能沒有得到您的控制。

在正在使用您的控件,嘗試重寫RaisePostbackEvent並調用RaisePostBackEvents每個控件的頁:

protected override void RaisePostBackEvent(IPostBackEventHandler sourceControl, string eventArgument) 
{ 

    this.yourcustomcontrol1.RaisePostBackEvent(sourceControl, eventArgument); 
    this.yourcustomcontrol2.RaisePostBackEvent(sourceControl, eventArgument); 

    base.RaisePostBackEvent(sourceControl, eventArgument); 
} 
+0

,它甚至沒有打電話RaisePostBackEvent。我剛剛嘗試過。 – MsBugKiller 2010-06-30 16:24:20

+0

埃德,謝謝你回覆我的帖子。 – MsBugKiller 2010-10-08 15:09:04

+0

探針是我的結構不同回發之間。 – MsBugKiller 2010-10-08 15:11:12