Reputation: 8734
I have a placeholder control within an UpdatePanel, and when the Add Vehicle button is clicked, I need a new "row" of controls to appear (The first "row" is added declaratively). The UserControl however gets added but not displayed. How can I fix this?
protected void AddVehicleButton_Click(object sender, EventArgs e)
{
int count = Convert.ToInt32(VehicleRegistrationCountHiddenField.Value);
var TBId = "VehicleRegistrationEnhancedTextBox" + count;
IList<Panel> oldPanels = (IList<Panel>)Session["VehiclePanels"] ?? new List<Panel>();
//Seperator
Literal hr = new Literal { Text = "<HR/>" };
//Vehicle Registration
UserControl uc = new UserControl(){ID="3"};
uc.LoadControl("~/Controls/ImageUploadAndCrop/ImageUploadAndCrop.ascx");
Label vehicleRegistration = new Label
{
ID = TBId + "_Label",
AssociatedControlID = TBId,
Text = "Vehicle Registration:"
};
EnhancedTextBox vehicleTypeTextBox = new EnhancedTextBox
{
ID = TBId,
Required = true,
RequiredErrorText = "Vehicle Registration is a required field."
};
//Readd previously added panels
foreach (var addedPanel in oldPanels)
{
AddVehiclePlaceholder.Controls.Add(addedPanel);
}
//Add new controls to the form
Panel newPanel = new Panel();
newPanel.Controls.Add(hr);
newPanel.Controls.Add(uc);
newPanel.Controls.Add(vehicleRegistration);
newPanel.Controls.Add(vehicleTypeTextBox);
AddVehiclePlaceholder.Controls.Add(newPanel);
//Increment the ID count
count++;
VehicleRegistrationCountHiddenField.Value = count.ToString();
//Save the panel to the Session.
oldPanels.Add(newPanel);
Session["VehiclePanels"] = oldPanels;
}
The html is below:
<div id="Step2" style="" data-step="2">
<h2> Step 2 (optional): Capture the offender(s) vehicle Information. </h2>
<hr>
<div id="VehicleTypeFields">
<div>
<label for="">Vehicle Registration</label>
<div id="Body_Body_UpdatePanel1">
<div>
<div>
<script type="text/javascript" src="/Controls/ImageUploadAndCrop/Javascript/jquery.Jcrop.min.js">
<link type="text/css" rel="stylesheet" href="/Controls/ImageUploadAndCrop/CSS/jquery.Jcrop.css">
<script type="text/javascript">
<div>
<div id="Body_Body_VehicleRegistrationImageUploadAndCrop_UploadPanel">
</div>
<input id="Body_Body_VehicleRegistrationEnhancedTextBox" type="text" placeholder="CA123-456" name="ctl00$ctl00$Body$Body$VehicleRegistrationEnhancedTextBox">
</div>
</div>
</div>
</div>
<div id="Body_Body_AddVehiclesUpdatePanel">
<input id="Body_Body_VehicleRegistrationCountHiddenField" type="hidden" value="2" name="ctl00$ctl00$Body$Body$VehicleRegistrationCountHiddenField">
<div>
<hr>
<label id="Body_Body_VehicleRegistrationEnhancedTextBox1_Label" for="Body_Body_VehicleRegistrationEnhancedTextBox1">Vehicle Registration:</label>
<input id="Body_Body_VehicleRegistrationEnhancedTextBox1" type="text" name="ctl00$ctl00$Body$Body$VehicleRegistrationEnhancedTextBox1">
<span id="Body_Body_VehicleRegistrationEnhancedTextBox1_RequiredFieldValidator" style="display:none;">Vehicle Registration is a required field.</span>
</div>
</div>
</div>
Upvotes: 2
Views: 682
Reputation: 7415
The problem is your use of LoadControl on a new instance of UserControl rather than the page's implementation. IE rather than this:
UserControl uc = new UserControl(){ID="3"};
uc.LoadControl("~/Controls/ImageUploadAndCrop/ImageUploadAndCrop.ascx");
Do this instead:
Control uc = LoadControl("~/Controls/ImageUploadAndCrop/ImageUploadAndCrop.ascx");
uc.ID = 3;
I think that will fix your immediate problem with nothing displaying but there are still other issues. While it might be possible to store the entire control in session state, my own testing shows there are anomolies in doing so. I would instead make sure you give each instance of your user control a unique ID (not "3" every time), and store those ID's somewhere. Then loop thru those ID's, calling LoadControl for each one, setting the control ID as you loop (this is required in order for the past viewstate to be reapplied to your user control.
I would also move that loop to either Page_Init or Page_Load so that your dynamically created user controls can properly participate in the page's lifecycle. Creating them in that click event is too late for them to catch their own events and they won't be created at all in the case of a postback outside of that click event.
Upvotes: 1