ASP.NET User Control Not Retaining Postback Values

All,

I’ve been banging my head against the wall for hours now, and my co-workers don’t have an answer either.

We’re expanding a user information portal to include international phone numbers, so one of our devs created a .NET user component with a dropdown for the country codes and a text box for the phone number.

When the form is first invoked, data is retrieved from vars in the previous form and both values in the component are populated correctly. When the form is posted back, the text box retains the phone number just fine, but the dropdown isn’t retaining anything.

We do databind the dropdown to a list of country codes in the component’s PageLoad method. I’ve traced through the code there, and the dropdown’s SelectedIndex property changes from -1 to 0, which is not correct.

It would help if I knew when the postback values are assigned to the vars again - the vast majority of our work is stuck in Classic ASP, and it’ll be even harder to get justification to move the rest of the site over if we can’t get to the bottom of this one quickly.

Thanks in advance for your help.

Jim Stanley
Blackboard Connect Inc.

Are you checking the IsPostBack value when loading/binding the page?

Yes, I am checking for that. After reviewing the load method sequence, I’m beginning to wonder if data binding should occur in the component’s Page_Init method instead of Page_Load where it is now. Would that do any good?

Can you show your code? That would make it much easier to troubleshoot.

Okay, here’s a condensed version of the page load method. This is the only place where values are set. Vars should be fairly self-explanatory, fCountryCode being the dropdown and fPhoneNumber being the text box. Initial underscores are internal values to the component. It looks as if the internal properties get set in the page_init, so probably my next step is to look there. If you need more let me know.

protected void Page_Load(object sender, EventArgs e)
{
lPhoneHeaderLabel.Text = _phoneHeaderLabel;
lCountryCode.Text = _countryCodeLabel;
lPhoneNumber.Text = _phoneNumberLabel;

	if (!_isInternational)
	{
	  // don't show the country dropdown
		lCountryCode.Visible = false;
		fCountryCode.Visible = false;
		lPhoneNumber.Visible = false;
	}
	else
	{
		fCountryCode.DataSource = _countryCodeList;
		fCountryCode.DataValueField = "Code";
		fCountryCode.DataTextField = "Name";
		fCountryCode.DataBind();
	}

	if (!IsPostBack)
	{
		// if (_countryCode != null)
		// {
		fCountryCode.SelectedValue = _countryCode;
		// }
		fPhoneNumber.Text = _phoneNumber;
	}
	else
	{
	  // test code - this is showing as null
		string trash = Request.Form[fCountryCode.ClientID];
		fCountryCode.SelectedValue = Request.Form[fCountryCode.ClientID];
	}

}

Let’s walk thru it quickly:

On first running (before postback), your code is rebinding the dropdown then setting the selected value.

On postback, your code is rebinding the dropdown (again) and not setting the selected value.

When it rebinds, it loses the selected value (because it has to clear and recreate the Items collection).

Hope that helps.

My tip would be to use the OnInit event to databind the list to avoid ViewState bloat. After that, the Page lifecycle should take care of the rest. It will reapply any selected value prior to OnLoad for subsequent postbacks.

Cheers,
D.

That IsInternational check should be within the If(!IsPostBack).

Thanks all!

We did indeed put it in the OnInit() method, which is when (we found out) the ViewState values get assigned. A few more tweaks to the component and all appears to be well.

Thanks again.

Jim Stanley
Blackboard Connect Inc.

ViewState values are restored between OnInit and OnLoad.

Cheers,
D.