Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problems synchronizing events in web forms using web user controls

Status
Not open for further replies.

TZRick

Programmer
Nov 10, 2002
11
US
Hello everyone.

I have just begun using Web User Controls in my Web Forms. The problem I am having is that the contents of the controls take two page load events before ViewState contents are successfully shown in modules as well as WebForm1. I need a way to be able to update all controls with one click in WebUserControl1. Any help will be appreciated. If you need more info, please specify. The code is quite lengthy. As you can see, I did try to Bubble the event from the control to the form. The bubbling works, but the ViewState is not updated until after two clicks. I even tried using a member variable inside WebUserControl1 in place of ViewState, but I get the same result.

Note: When I call the method to update from the click event handler in WebUserControl1, that control is successfully updated, but the rest of controls in WebForm1 are not. They occur the next time the Page Load is called.

I have two custom controls: WebUserControl1 and ShowFilesControl1, both used in WebForm1.
In addition, there is a Label in WebForm1 called lblCurrentPath.

WebUserControl1:
Contains a table with dynamic hyperlink controls that are used for updating the table's contents. Sets and retrieves "Path" information from ViewState: string getCurrPath (), void setCurrPath (string strCurrPath). Contains event handlers that handle click events that update the ViewState.

Main Methods: redrawTable (string path): Clears and repopulates table with updated info based on path. Calls setCurrPath (path). Is called by click event handlers as well as WebForm1's Page Load event.

ShowFilesControl1:
Contains a table with dynamic objects. Table is changed when showFiles (string strPath) method is called.

WebForm1:
using...
namespace webcontrol
{
public class WebForm1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Label lblText;
protected System.Web.UI.WebControls.Label lblCurrentPath;
protected System.Web.UI.WebControls.Button btnSubmit;
protected WebUserControl WebUserControl1;
protected ShowFilesControl ShowFilesControl1;

private void Page_Load(object sender, System.EventArgs e)
{
if (!IsPostBack)
{
WebUserControl1.setCurrPath ("My Computer");
}

loadAll ();

}

protected void loadAll ()
{
WebUserControl1.redrawTable (WebUserControl1.getCurrPath ());
lblCurrentPath.Text = WebUserControl1.getCurrPath ();
ShowFilesControl1.showFiles (WebUserControl1.getCurrPath ());

return;

}

private void WebForm1_BubbleClick(object sender, EventArgs e)
{
Response.Write ("Event successfully registered. <br>");
loadAll ();
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}

private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
WebUserControl1.BubbleClick += new EventHandler(WebForm1_BubbleClick);

}
#endregion
}
}
 
ViewState is the best and worst thing that ever happened to ASP.

The problem is that in the Page Lifecycle, LoadViewState comes before Page_Load, and Page_Load comes before any events. So when you bubble the event, ViewState has already been loaded for that Request, which is why you don't see your changes get propagated to the other controls.

There's no way to short-circuit this behavior. What you must do, instead, is figure another approach to the problem.

The Items collection of the HttpContext object is a great little tool, which acts like a temporary session object. It only lives as long as the request, but allows you to place references to objects in there that you wish to be available to all other objects during that request.

You still have lifecycle issues to deal with, however. You must pay close attention to when you place items in there, and if the events that you wish to have access to those items are "downstream" from where you are.

Typically, PreRender events will fire after Load events, so that's a good heuristic to follow. It's not 100%, though. PreRender will always fire after Load in a single object, but when you're communicating with another UC, that model will sometimes break.

What I have found to ALWAYS be true is that the Init event will always fire prior to Load, so if you can make use of that behavior, I encourage you to do so.

Want my real advice, though? Avoid this altogether by placing all objects that must share ViewState with each other in a single object whenever possible. If it's not possible, though, you must tango with the page lifecycle. Personally, I think this is the first stumbling block that separates the men from the boys (so to speak) in ASP.NET. You will encounter instances where you have to get pretty creative with your message passing.

Remember that Init is your friend, and to ignore all the mess that MS puts in there saying "Don't touch this event, or your code won't work, etc... etc...".

Good luck.

-paul

penny.gif
penny.gif

The answer to getting answered -- faq855-2992
 
Paul,

THANK YOU SO MUCH for the help! I have been struggling with this problem since last week and it has been killing me! You have really helped me out big time!

Thank you again so much!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top