EditForceAnUpdate on Container Widgets
EditIntroduction to ForceAnUpdate
Gaia Ajax Widgets is different to other Ajax Frameworks in that Gaia tries as seldom as possible to do what is known as "partial rendering". Instead Gaia tries to send as little as possible over the wire and instead communicate between the server and the client towards "wrapper objects" on the client. This first of all significantly reduces the bandwidth but also have several other advantages which are explained in the; "Gaia Ajax Widgets and ASP.NET" section under the Related Pages tab.
Every once in a while however you must resort to partial rendering, this can be because of the Gaia Engine doesn't understand what you are trying to do, or it can be because of that you are interacting with "conventional" ASP.NET postback WebControls. Here comes "ForceAnUpdate" to the rescue.
ForceAnUpdate can be called on all of your "Container Widgets" meaning e.g. Panel, MultiView, Window and so on. Basically all controls which can have child controls within themselves. If you call ForceAnUpdate then the entire widget will be re-rendered and all of its HTML will be "flushed" back to the client. Note that this is a VERY expensive operation in regards to bandwidth usage and should be avoided as often as possible. This is basically the way ASP.NET AJAX works with their "UpdatePanels" which are entirely built around the concept of Partial Rendering.
EditWhen to use ForceAnUpdate
First of all, you very rarely need to use it, but;
- If you in any ways have changed the Controls collection of your Container Widget, e.g. you have added or deleted child controls from it. Then you should use ForceAnUpdate.
- If you have "conventional" ASP.NET controls like an ASP.NET Button, TextBox or 3rd part control inside of a Gaia Container Widget, then you can use ForceAnUpdate to re-render those widgets in an Ajax Callback.
Except for those two scenarios there are no places you need to use the ForceAnUpdate methods of the Gaia Container Widgets. Note also especially that if you create dynamically created controls due to an ajax callback or something then you should call ForceAnUpdate only the first time you want those controls rendered back to the client. If you then in the next callback want to trap events for those controls then you must due to HTTPs statelessness re-create those controls, but you do not need to call ForceAnUpdate to re-render them on the client!
Partial Rendering is a very expensive operation and should be avoided as much as possible!
EditUseful scenarios for when to use ForceAnUpdate
There are a lot of useful scenarios where ForceAnUpdate can be very useful for you. One particulary useful scenario is where you are dynamically loading UserControls to display within a container widgets for your users. Here it can be very useful to dynamically load the UserControls, put them into a container widget and call ForceAnUpdate on the container widgets. Gaia has 100% compatibility towards conventional ASP.NET which means that this will except for the ForceAnUpdate method call be exactly the same code in conventional ASP.NET as it is in Gaia.
 Dynamic Controls Added |
EditSample of ForceAnUpdate - Loading UserControls dynamically
EditFile called; WebUserControl1.ascx
<%@ Control
Language="C#"
AutoEventWireup="true"
ClassName="WebUserControl1" %>
<%@ Register
Assembly="Gaia.WebWidgets"
TagPrefix="gaia"
Namespace="Gaia.WebWidgets" %>
<script type="text/C#" runat="server">
protected void btn_Click(object sender, EventArgs e)
{
btn.Text = "Thank you for clicking me...";
}
</script>
<gaia:LinkButton
runat="server"
ID="btn"
OnClick="btn_Click"
Text="Click me..." />
EditFile called; WebUserControl2.ascx
<%@ Control
Language="C#"
AutoEventWireup="true"
ClassName="WebUserControl1" %>
<%@ Register
Assembly="Gaia.WebWidgets"
TagPrefix="gaia"
Namespace="Gaia.WebWidgets" %>
<script type="text/C#" runat="server">
protected void btn_Click(object sender, EventArgs e)
{
lbl.Text = "Hello WORLD, Ajax world, Web World 2.0 ;)";
}
</script>
<gaia:Label
runat="server"
Text="Hello who?"
ID="lbl" />
<br />
<gaia:Button
runat="server"
ID="btn"
OnClick="btn_Click"
Text="Click me..." />
EditFile called; Default.aspx
<%@ Page
Language="C#"
AutoEventWireup="true"
ClassName="_Default" %>
<%@ Register
Assembly="Gaia.WebWidgets"
TagPrefix="gaia"
Namespace="Gaia.WebWidgets" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Ajax Sample</title>
</head>
<body>
<form id="form1" runat="server">
<gaia:DropDownList
runat="server"
ID="dropper"
AutoPostBack="true"
OnSelectedIndexChanged="dropper_SelectedIndexChanged">
<Items>
<asp:ListItem Text="Pick a control to load..." />
<asp:ListItem Text="WebUserControl1.ascx" />
<asp:ListItem Text="WebUserControl2.ascx" />
</Items>
</gaia:DropDownList>
<br />
<gaia:Label
runat="server"
Text="Pick a UserControl to load from the above DropDownList"
ID="lbl" />
<gaia:Panel
runat="server"
style="width:300px;height:250px;background-color:#eee;border:solid 1px Black;margin:15px;"
ID="container">
</gaia:Panel>
</form>
</body>
</html>
C# codebehind
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
// We need to RE-load any previously loaded dyanmically created
// controls on every consecutive callback(postback in order to
// be able to trap EVENTS in them
// Unless we do this then we will NOT be able to trap Events
// which our widgets are firing...
// This is NOT something unique for Gaia, but a part of the
// Gaia's heritage from ASP.NET which again is ASP.NET's
// heritage from HTTP
// But for some reasons people tend to do more "flexible things"
// and more "cool things" with Gaia than they tend to do with
// conventional ASP.NET and therefor this more often is a
// question in our forums than in the forums of ASP.NET
string userCtrlToLoad = ViewState["loadedControl"] as string;
if (userCtrlToLoad != null)
{
Control userControl = Page.LoadControl(userCtrlToLoad);
container.Controls.Add(userControl);
}
}
}
protected void dropper_SelectedIndexChanged(object sender, EventArgs e)
{
string userControlName = dropper.SelectedValue;
lbl.Text = userControlName;
Control userControl = Page.LoadControl(userControlName);
// Must clear PREVIOUS controls away from Container Widget
container.Controls.Clear();
// Adding up newly loaded UserControl and calls ForceAnUpdate
// to make sure we RE-render the control back to the client
container.Controls.Add(userControl);
container.ForceAnUpdate();
// Due to HTTP's statelessness we need to be able
// to RE-load this control on EVERY consecutive postback/callback
// this we do by setting a "Signal Flag" in our ViewState
// which we can check for existance for in every consecutive
// callback and if it exists load up the right UserControl
// to be able to trap Events and so on in it.
ViewState["loadedControl"] = userControlName;
}
So as you can see from the above code example, the ForceAnUpdate method can be very powerful in regards to adding really complex and rich Ajax features up into your web applications. By combining the ForceAnUpdate method with dynamically loading UserControls there is virtually no limits to the amount of complexity you can add up into your Ajax applications. Without compromising best practices like OOP, OOA and OOD. In addition to keeping the level of cohesion very good. If you are using UserControls this way you also keep your application very DRY, declarative and you have a good "separation of concerns".
EditForceAnUpdateWithAppending
ForceAnUpdateWithAppending is the "little brother" of ForceAnUpdate but instead of forcing a re-render of already rendered controls it will only render Gaia controls in the Control Collection of the Container Widget which has not been rendered from before. This is a significant improvement above the ForceAnUpdate method and has some very interesting uses. Though be aware of that all controls rendered in this manner will be APPENDED on the client-side, regardless of where in the control tree they actually exists. A very nice place this type of logic is useful though is for "continously feeding container widgets with children" like in our Ajax Live Scroll Sample.