views:

48

answers:

3

I've created 2 controls to manipulate a data object: 1 for viewing and another for editing.

On one page I load the "view" UserControl and pass data to it this way:

ViewControl control = (ViewControl)LoadControl("ViewControl.ascx");
control.dataToView = dataObject;
this.container.Controls.Add(control);

That's all fine and inside the control I can grab that data and display it.

Now I'm trying to follow a similar approach for editing. I have a different User Control for this (with some textboxes for editing) to which I pass the original data the same way I did for the view:

EditControl control = (EditControl)LoadControl("EditControl.ascx");
control.dataToEdit = dataObject;
this.container.Controls.Add(control);

Which also works fine.

The problem now is getting to this data. When the user clicks a button I need to fetch the data that was edited and do stuff with it. What's happening is that because the controls are being added programmatically, the data that the user changed doesn't seem to be accessible anywhere.

Is there a solution for this? Or is this way of trying to keep things separated and possibly re-usable not possible?

Thanks in advance.

A: 

Controls created dynamically must be added on Init or PreInit event on the page.

You have to do it here because controls state is not yet loaded. If you add the the control AFTER you'll have them empty since the page already filled control page values early in the page life cycle.

More info about page life cycle here

Claudio Redi
It's interesting you say that, because I'm adding the controls on the Page_Load event and I can still access the values inside the controls of the loaded control. Is there something else I should be aware of?
Farinha
+1  A: 

Just keep a reference to the control as a variable in the page's code-behind. I.e.

private EditControl control;

protected void Page_Init(object sender, EventArgs e)
{
   control = (EditControl)LoadControl("EditControl.ascx");
   control.dataToEdit = dataObject;
   this.container.Controls.Add(control);
}

protected void Button_Click(object sender, EventArgs e)
{
   var dataToEdit = control.dataToEdit; 
}

As long as you're creating the control in the right part of the page's lifecycle (Initialization) then ViewState will be maintained. I'm assuming dataToEdit is just a TextBox or something?

GenericTypeTea
That was useful, thanks. This way I don't need to go and find the Control inside the Placeholder, I can just use the reference to it.
Farinha
A: 

Here's my solution:

In the page, I keep a reference to the control that is loaded programmatically. In the control I created a GetData() method that returns an object with the data entered by the user. When the user submits the form, the page calls the GetData() method on the control to access the data the user entered.

Farinha
So you basically used my answer and just added another method to return the value of the control?
GenericTypeTea
Well, yeah.I had to create the method because the control's child controls are not accessible from the page where I do the LoadControl().
Farinha