ViewState not restoring in composite control (ASPNET2)

M

Mark Olbert

I have a "master" composite control which, in turn, holds an instance of a "detail" composite control (the "master" control will
ultimately contain multiple instances of the "detail" control, but I'm keeping things simple to try and figure out what's going
wrong). The master control supports databinding.

Upon postback, the detail control is not retrieving its state from ViewState after it is created and added to the master control
during the master's CreateChildControls() call. Yet if I create a separate, standalone instance of the detail control on the same
web page, the standalone instance does get properly configured from ViewState on postback. So why doesn't the instance of the detail
that's created by the master do the same thing?

Here is the definition of the master control:

[DefaultProperty("Text")]
[ToolboxData("<{0}:Survey runat=server></{0}:Survey>")]
public class Survey : CompositeControl
{
private SurveyDefinition surveyDS;
private SurveyQuestion test;

[
Bindable(true),
Category("Data"),
DefaultValue(null),
Description("The SurveyDefinition dataset to bind to"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
]
public virtual SurveyDefinition DataSource
{
get { return surveyDS; }
set { surveyDS = value; }
}

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

test = new SurveyQuestion();
test.ID = "question1";

if( DataSource != null )
test.Text = DataSource.question[0].text;

Controls.Add(test);

return;
}
}

Here is the detail:

[DefaultProperty("Text")]
[ToolboxData("<{0}:SurveyQuestion runat=server></{0}:SurveyQuestion>")]
public class SurveyQuestion : CompositeControl
{
private Label lblQuestion;

public SurveyQuestion()
{
}

[
Bindable(true),
Category("Appearance"),
DefaultValue("abcd"),
Description("The question text"),
]
public string Text
{
get
{
EnsureChildControls();
return lblQuestion.Text;
}

set
{
EnsureChildControls();
lblQuestion.Text = value;
}
}

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

lblQuestion = new Label();
lblQuestion.ID = "lblQuestion";

Controls.Add(lblQuestion);
}
}

????

- Mark
 
S

Steven Cheng[MSFT]

Hi Mark,

I think the problem in your composite control is likely due to you set the
Child control's property (when perform databinding) before you add it into
the parent container's Controls Collection. We need to set property (which
you want them to be persisted or tracked by viewstate ) after the control
is added into the container's Controls collection. Here is two test control
I've made which work as expected. You can have a look at them for detailed
reference:

==========Question Control=========
namespace ControLibrary
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:MyQuestionControl
runat=server></{0}:MyQuestionControl>")]
[Designer(typeof(MyQuestionControlDesigner),typeof(IDesigner))]
public class MyQuestionControl : CompositeControl
{
private Label _lbl;
private TextBox _txt;
private Button _btn;

public MyQuestionControl()
{
}


[Bindable(true)]
[Category("Appearance")]
[DefaultValue("Default Text")]
[Localizable(true)]
public string Text
{
get
{
EnsureChildControls();
return _lbl.Text;
}

set
{

EnsureChildControls();
_lbl.Text = value;
}
}


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

_lbl = new Label();
_lbl.ID = "lblText";
_lbl.EnableViewState = true;

_txt = new TextBox();
_txt.ID = "txtText";

_btn = new Button();
_btn.ID = "btnSubmit";
_btn.Text = "Submit";
_btn.Click += new EventHandler(btn_Click);


Controls.Add(new LiteralControl("<br/>"));
Controls.Add(_lbl);
Controls.Add(_txt);
Controls.Add(_btn);


}



private void btn_Click(object sender, EventArgs e)
{
_lbl.Text = _txt.Text;
}
}

public class MyQuestionControlDesigner : ControlDesigner
{
public override string GetDesignTimeHtml()
{
MyQuestionControl question = Component as MyQuestionControl;

string str = "<font size='20'>MyQuestionControl:{0}</font>";

return string.Format(str, question.Text);
}
}
}
=============================

=========Question Container===========
namespace ControLibrary
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:QuestionContainer
runat=server></{0}:QuestionContainer>")]
[Designer(typeof(QuestionContainerDesigner),typeof(IDesigner))]
public class QuestionContainer : WebControl, INamingContainer
{
private bool _databind = false;

private MyQuestionControl[] _questions;

public string[] DataSource = null;

[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public string Text
{
get
{
String s = (String)ViewState["Text"];
return ((s == null) ? String.Empty : s);
}

set
{
ViewState["Text"] = value;
}
}

protected override void CreateChildControls()
{

_createQuestions(_databind);
ChildControlsCreated = true;
}

private void _createQuestions(bool databind)
{
Controls.Clear();


if (!databind && ViewState["COUNT"] != null)
{
int count = (int)ViewState["COUNT"];
DataSource = new string[count];
}
else if(!databind && ViewState["COUNT"] == null)
{
Controls.Add(new LiteralControl("<br>Empty..."));
return;
}

int len = DataSource.Length;
_questions = new MyQuestionControl[len];

for (int i = 0; i < len; ++i)
{
MyQuestionControl question = new MyQuestionControl();
_questions = question;

question.ID = "q" + i;
Controls.Add(question);


if (databind) question.Text = DataSource;

}
}


public override void DataBind()
{

_databind = true;
CreateChildControls();

ViewState["COUNT"] = DataSource.Length;

}
}


public class QuestionContainerDesigner : ControlDesigner
{
public override string GetDesignTimeHtml()
{

string str = "<font size='20'>QuestionContainer
Control:{0}</font>";

return string.Format(str, string.Empty);
}
}
}
=============================

Hope this helps.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,906
Latest member
SkinfixSkintag

Latest Threads

Top