2010-06-30 8 views
0

Je crée une bibliothèque de contrôles personnalisés. Mes contrôles sont hérités de CompositeControl. En fonction de la réponse de l'utilisateur, je dois insérer plus de contrôle personnalisé. J'ai un PlaceHolder (_ph) passé à partir du code client. J'insère mes contrôles dans ce PlaceHolder.Les contrôles personnalisés ASP ne déclenchent pas les événements corrects

Mon problème est le contrôle que j'ai inséré dans le gestionnaire d'événements ne déclenche pas son événement, mais il déclenche l'événement parent. Par exemple, si j'ai un EddDropDown A, et que l'utilisateur choisit une réponse, je dois créer EddDropDown B et C dans edd_SelectedIndexChanged. Lorsque je choisis une réponse pour B, il déclenche SelectedIndexChanged pour A au lieu de B.

Je pense que cela a quelque chose à voir avec l'entrée tardive du cycle de la page. Je ne sais pas comment le réparer. S'il vous plaît aider. Vraiment apprécier un assistant. Merci d'avance.

ceci est un exemple de mes contrôles:

using System; 

utilisant System.Collections.Generic; en utilisant System.Collections;

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

espace de noms CommerceBank.DueDiligence.ClientFacade.WebForms { de EddDropDownListArgs public class: EventArgs {private int _iQuestionID; chaîne _sAnswer = chaîne.Empty; private 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); 
      } 
     } 

    } 



} 

}

C'est le code qui crée les contrôles:

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

Il y a quelques petites choses que je ne l'ai pas nettoyé, mais vous voyez l'idée.

Répondre

0

Les événements de publication peuvent ne pas être contrôlés.

Dans la page qui utilise vos commandes, essayez redéfinissant la RaisePostBackEvent et appeler les RaisePostBackEvents pour chaque commande:

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

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

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

Il ne remet même pas RaisePostBackEvent. J'ai juste essayé. – MsBugKiller

+0

Ed, merci d'avoir répondu à mon message. – MsBugKiller

+0

Le problème était que ma structure n'était pas la même entre les publications. – MsBugKiller

Questions connexes