我正在构建一个自定义控件库。我的控件继承自CompositeControl。 根据用户的答案,我必须插入更多的自定义控件。我从客户端代码传入了PlaceHolder(_ph)。我将控件插入PlaceHolder。
我的问题是我在事件处理程序中插入的控件不会触发其事件,但会触发父事件。例如,如果我有一个EddDropDown A,并且用户选择了答案,我必须在edd_SelectedIndexChanged中创建EddDropDown B和C.当我为B选择答案时,它会为A而不是B触发SelectedIndexChanged。
我认为这与进入页面周期迟到有关。我不知道如何解决它。请帮忙。非常感谢任何助理。 提前谢谢。
这是我的控件的一个示例:
using System;
使用System.Collections.Generic; 使用System.Collections;
使用System.Linq; 使用System.Text; 使用System.ComponentModel; 使用System.Security.Permissions; 使用System.Web; 使用System.Web.UI; 使用System.Web.UI.WebControls; 使用CommerceBank.DueDiligence.ServiceProxies.Internal.Edd; 使用System.Collections.Specialized; 使用System.Runtime.Serialization;
命名空间CommerceBank.DueDiligence.ClientFacade.WebForms { public class EddDropDownListArgs:EventArgs { private int _iQuestionID; string _sAnswer = string.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);
}
}
}
}
}
这是创建控件的代码:
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(" "));
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 :(得分: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);
}