views:

650

answers:

5

Hello,

I am trying to build a server control that, depending on a "QuestionTypeId" display either a text box, date picker or Yes-No radio buttons.

I have my control displaying how I want it to, but when the submit button is pressed on the form, the text box, date picker or radio buttons that were generated in the RenderContents method are all null.

I have attempted to store the generated controls in view state, that stopped them being null, but the user inputs were not being stored.

I will post code if it is needed. Just ask.

A: 

When you add controls dynamically, you need to make sure they are recreated before the viewstate is restored.

I haven't done this in a while, but from memory I think you should recreate your controls in the OnInit method. This happens before postback data has been loaded and before the controls have their values set from viewstate.

It may be worth doing some reading on the asp.net page lifecycle:

http://msdn.microsoft.com/en-us/library/ms178472.aspx

Winston Smith
+1  A: 

I think you need to create (and add) the controls in CreateChildControls. This will mean you'll need to store the value of the QuestionTypeId in either Viewstate or ControlState (I'd argue that ControlState is applicable in this case, as your control can't work without this value).

David Kemp
That's exactly why ControlState is applicable - because the control cannot work without the value.
Slavo
A: 

You can create a user control and use server controls for textbox, datepicker, radiobuttons.

If you create a cusom server control then you have to add the posted data to your control properties. You can do this at your control OnInit event:

MyProperty = Request.Form("myControl");
dexter
That's a bit old school?
David Kemp
A: 

A simpler method would be to create all the controls at design time and make the controls invisible based on you requirements.

Example code:

protected void Page_Load(object sender, EventArgs e)
{
    txtBox.Visible = QuestionTypeID == 1;
    chkBox.Visible = QuestionTypeID == 2;
}

If you do use dynamic controls you should do as David pointed out, save the value QuestionTypeID in ViewState or ControlState and then create the control you want based on that value.

(the control needs to be created every time the page loads even on a post back and they cannot be created later in the page life cycle then the Page_Load method if you want their ViewState persisted and recovered)

Example code:

protected void Page_Load(object sender, EventArgs e)
{
    var questionId = ViewState["QuestionTypeID"];

    if(questionId == /* Value to create TextBox */) {
        var txt = new TextBox { ID = "txt" };
        placeHolder.Controls.Add(txt);
    } else if(questionId == /* Value to create Calender */) {
        var cal = new Calender { ID = "cal" };
        placeHolder.Controls.Add(cal);
    }

    /* Once the controls are added they will be populated with the posted values */
}

P.S.
It's always a good idea with dynamic controls to specify the ID.
You can save the added controls to member variables and use them elsewhere (after they are assigned)
You can subscribe to their events and if the user posted a new value your method will be called

Y Low
A: 

Hello,

I have followed your advice and done the following:

1) Question Type is stored in view state in my server control.

2) on CreateChildControls now creates a new instance of my control and adds it to a place holder on the page.

My problem now is that things seem to fire in bit of an odd order:

1)On initial load of page, create child controls is fired and the RenderContents method of my server control fires.

2)A button is clicked to load a new contact, this triggers create child controls and RenderContents is fired.

3)details are entered and save is pressed, this triggers Create Child Controls but RenderContents is not triggered and a NullReferenceException is generated by trying to access my control to get the value out. (If i skip the code that access my controls, RenderContents is called and renders.

Seconly, another issue is that when I try an set a value (onDataBind) I try to access the Text box that has been generated in my server control and get another NullReferanceExeption

Thoughts?

Richard Priddy