Why does the updatepanels reload controls outside the updatepanel - c#

I have several UpdatePanels on a page and they have been set with a mode of Conditional. I see a flicker in the controls outside of the UpdatePanels when there is an event that occurs within the UpdatePanel (Say a button click).
The page doesn't post back but the user experiences a "Flicker".
Any idea what might be going on here?

I think you might have got the UpdateMode wrong.
By default it is 'Always' if you change it to 'Conditional' it should fix your problem

Do you have event handlers for controls inside the UpdatePanels that make updates to controls outside of the UpdatePanels?
You could try selectively commenting event handlers until it stops flickering to find the culprit.
I also found Firebug to be useful in these cases - you can see the exact HTML going into the updated regions.

You don't say what the callback inside the UpdatePanel is doing.
If it is updating the contents of the panel itself, it could be be the browser is simply repainting the entire page layout to account for the new content just as it would if you resized the browser window.

Related

Prevent button_click event in page refresh in c#

I want to prevent button_click event in page refresh.
I have searched but can not get any solution relevant for me.
I have found this one:
http://www.dotnetspider.com/resources/42823-How-Avoid-Re-Submitting-Data-Page-Refresh.aspx
But i do not need to go inside button_click event in page refresh.
Response.Redict("") also not relevant here as i am returning label text after succesful button_click.
What you looking for is not so simple.
The solution you can use for sure is the Post/Redirect/Get design pattern
or use some code that tries to detect the refresh of the page on:
http://www.codeproject.com/KB/aspnet/DetectingRefresh_.aspx
http://dotnetslackers.com/community/blogs/simoneb/archive/2007/01/06/Using-an-HttpModule-to-detect-page-refresh.aspx

Viewstate and controls in ASP.NET

I posted a question a couple of days ago about viewstate and after running some tests I have come to some conclusions/results. Based on these results I have a few questions as to how someone would do certain things.
Here are the results of my tests that I ran:
If usercontrolA is loaded from OnInit of a Page, then his viewstate will be available in OnLoad. All other controls that usercontrolA loads from it's OnInit, will have their viewstate ready in their OnLoad.
If usercontrolA is loaded from OnLoad of a Page, then his viewstate will be available in OnPreRender. All other controls that usercontrolA loads from it's OnLoad, will have their viewstate available in their OnPreRender.
If usercontrolA is loaded from an event (Example: button click. Events fire after OnLoad and before OnPreRender) of a Page, then his viewstate will not be available. All other controls that usercontrolA loades will not have their viewstate available.
So in a perfect world you would always load all controls using situation #1, so that their viewstate is available on their OnLoad. Unfortunately when you need to load a control from a button click or from a OnLoad, is there no way for control to get its viewstate before OnPreRender stage?
I have read a bunch of articles on viewstate and thought I understood it, but working on my current application which loads usercontrols which load other usercontrols, I am having a real hard time with being able to get viewstate on my leaf (last in the chain) usercontrol.
Any suggestions and/or links are appreciated.
I don't think I can add anything that this article doesn't cover.
Look specifically at the Life Cycle Events section.
http://msdn.microsoft.com/en-us/library/ie/ms178472.aspx
It is accepted practice to load dynamic controls in OnInit, so that they get the full control lifecycle. I'm not sure I particularly understand your situation though - if you're loading a control based on a button click, why would it have viewstate at that point? On the next OnInit, you should load the control again (I usually use a page level Viewstate item to track that a particular control needs to be loaded) so that it can restore from Viewstate. Something like:
class Default : Page {
enum LoadedControl { Textbox, Label, GridView }
override OnInit() {
if (IsPostback) {
var c = Viewstate["LoadedControl"] as LoadedControl;
if (c != null) LoadDynamicControl(c);
}
}
void Button_Click() {
var c = (LoadedControl)Enum.Parse(typeof(LoadedControl), ddl.SelectedValue);
LoadDynamicControl(c);
}
void LoadDynamicControl(LoadedControl c) {
switch (c) {
case LoadedControl.Textbox:
this.ph.Controls.Add(new Textbox());
break;
...
}
ViewState["LoadedControl"] = c;
}
}
The slightly more interesting bit, though, is that according to catch-up events - it really shouldn't matter. The callstack for dynamically loading a control looks something like:
Control.Controls.Add(Control)
Control.AddedControl(Control)
Control.LoadViewStateRecursive(object)
Control.LoadViewState(object)
Taking Label as an example, it overrides LoadViewState and pulls it's Text property directly from ViewState. TextBox is similar. So, by my reading, it should be OK to add at any point, and then access ViewState. That doesn't seem to be jive with my experience, though, so further investigation seems warranted.
I'm surprised but interested about your results. When I work with dynamic controls I always add them in Page_Init. Anything else doesn't work. But you are right - how do you do it if you are adding them in response to a button click.
The only way I have found is by examining Request.Form("__EVENTTARGET") collection at PageInit. This contains the control ID of the control that has triggered the postback so for instance a button click. It will of course be qualified by the naming containers it appears in. Once you have identified the 'event' by this method you can add the controls you want.
It is of course all a bit hacky but it's the only way I found of doing these things. It does work.
It's interesting that the ViewState is available on PreRender if you add the controls at Page_Load. But as the above link indicates it too late to help you then. The controls state is rehydrated during the load cycle. If it's not there then your control state or dynamic controls are just going to disappear.
Did you try to use LoadComplete event?
Use this event for tasks that require that all other controls on the page be loaded.
This is fired after PageLoad and all events (ButtonClick, etc.), so your UserControls are are loaded in ButtonClick events, and in LoadComplete their ViewState is already initialized.

Loading ASP.NET user control at run time

I have an ASP.NET user control with a button, and I want to add it to the page when the user clicks a button from another user control. I have created an event handler to the first user control to handle it from the page and add the second user control to a page. Everything is working normally, but the button on the second user control doesn't respond to the event.
I place the second control on RadAjaxPanel
Note: When I add the second user control at design time its working fine.
All dynamically created controls should be added by the end of Page_Init (though sometimes you can get away with them added by the end of Page_Load).
If you're only adding them based on a button click event then you've done this in the event handers which fire AFTER Page_Init and Page_Load in the lifecycle - This is why your events don't fire and why it works fine when you add at design time.
This is because when a button is clicked on the second user control - the whole page lifecycle starts again. The page goes through Page_Load and Page_Init first and your control doesn't get loaded here. So, when the page lifecycle handles the "handle postback events" part, the control no longer actually exists, so the event doesn't fire.
Conversely, when you add at design time, the control exists in Page_Init and Page_Load so is able to handle the postback events from the user control because it already exists in the control tree - if this makes sense.
You need to think how you can restructure so they're added by the time Page_Load has finished at the very latest or it won't work. Without code samples or more detail it's hard to suggest exactly how you might do this. One possibility would be to set it visible instead of loading it outright - but if the control does some 'heavy lifting' on load like database hits or API calls then this might not be suitable for you.
I did something similar. What I did was to load some controls dynamically based on a selection from a DropDownList. If you have a method which loads the control for you, let's call it LoadControls(), then you can do something like this:
DropDownList_Click {
ViewState("LoadControls") = true;
LoadControls()
}
By setting the ViewState variable, you can then indicate Page_Load to load the controls on future postbacks:
Page_Load {
if (ViewState("LoadControls") == "true")
{
LoadControls();
}
}
This has the effect of then loading the control on-the-fly when the event first happens, and then at future times in the lifecycle.

How to ignore viewstate of a previous request for particular control?

I am dynamically generating controls, and sometimes I want to create a control and have it ignore the viewstate. For example, sometimes the user has clicked a button indicating they want a different form loaded, so the control tree I generate on postback is different from the original control tree. This is fine, except when I call Controls.Add then it tries to load the viewstate form the old controls into the new controls if the control tree structure is similar, and I want them to instead ignore that viewstate(and also ignore the postback values for input controls as well).
Can I do something like set the IDs of the controls or something that would allow me to conditionally prevent them from getting the viewstate/postback data of the previous request?
Edit: If I let the user of the control load the form on demand in postback handler, the postback data is not applied when I call Controls.Add(this really seems like a flaw in ASP.NET, because I would think if you're going to apply viewstate data "after the fact" through Controls.Add, it'd seem you would then apply the postback data automatically as well after the viewstate data is loaded). The real problem I run up against is my control is very dynamic, but the user of my control can't really tell it what to do until their postback handler fires, because one of the things a user can do is select different forms to be loaded via some link buttons. So it's not until the postback handler runs that they know what the uesr requested, and thus can ask my control to load a certain form. So I have to ask them to do convaluted things like saved the formID that identifies the last form to a session variable, and in OnInit they tell my form what the old formID was via a property. My control then loads the form in OnLoad so that it can consume the viewstate and postback data, and later in the programmer's postback handler, they can choose to clear the form and load a different one if they want.
Edit2: FYI Generating IDs for each control unique to the form works great, so I thought I could eliminate the pointless loading of the old form until the programmer requests a form be loaded in his postback handler. But as I mentioned above, what I found was that loading the form after postback data handling has occurred means that data is lost. Whereas viewstate gets loaded via Contorls.Add, playing catch up in the page lifecycle, it seems postback data does not! So it seems I am defeated at every turn.
You're going to avoid problems if you play along with the control lifetime. Basically, whenever you have a control that renders, it's best to ensure that control is recreated on the next postback, even if you aren't going to need it anymore. The first goal of a postback should be to restore the previous state -- only THEN do you make changes to it.
I described it best in this answer:
Wrong state in Server Controls with same ID's when dynamically adding UserControl to UpdatePanel
Giving the controls different ID's would certainly prevent ViewState from being loaded, that would be one way.
You may also be able to manipulate the ViewStateMode property of your controls by setting it to "Disabled". I'm not sure if this prevents it from loading (it definitely prevents them from saving viewstate), but you could try it.
Have you tried just calling controls.clear prior to adding in the new ones?
UPDATE
I'm starting to believe that you are generating the controls at the wrong point in the page lifecycle. What is your flow?
You must be generating dynamic controls on postback in pageload:
protected void Page_Load(object sender, EventArgs e)
{
--Generate Dynamic Controls--
}
You need to do it like:
protected override void OnInitComplete(EventArgs e)
{
base.OnInitComplete(e);
}
protected void OnInit()
{
--Generate Dynamic Controls--
}
protected void Page_Load(object sender, EventArgs e)
{
}

Webbrowser control in C# weird behavior

I'm setting a HTML string value to webbrowser.DocumentText. Problem is, sometimes it worked and sometimes it hangs up and not go through the documentcompleted event. what might be the problem?
Please reply, asap..
Thanks,
Jepe
Just a thought: With all the web-'dynam-ism' nowadays, a page is never really in a 'completely-loaded' state. After DocumentComplete, the OnLoad event of the page is fired, then any scripts placed in such an event are fired, and then javascript timers may be used to initiate download/upload of some resource, or a change in page using AJAX, etc.
I believe AJAX calls could cause all kinds of unseen problems with your WebBrowser control; because AJAX can cause multiple Navigating() events to fire during the loading of a page. And for that reason your app would experience multiple DocumentCompleted event fire on that page.
A possible solution could be to monitor the page changes and attempt to find out what possibly got changed. And to do this you may need to look into Notify method.
Called by MSHTML when a change occurs
in the contents of the markup
container with which it is
associated.
This and this discussion may help you coming up with something like following:
HtmlElement target = _webBrowser.Document.GetElementById("somedivthatwillbepopulatedbytheajaxrequest");
if (target != null)
{
target.AttachEventHandler("onpropertychange", new EventHandler(handler));
}

Categories