PDA

View Full Version : [FIXED] [V0.7] Nested dynamic controls don't behave correctly in Page Cycle



jchau
Nov 03, 2008, 9:13 PM
I have been stuck on this for almost 5 hours today. I have a form that is populated with dynamic user controls. On a Postback or AjaxEvent, the dynamic controls are playing catch up way too late in the page life cycle. The Init/Load events of the dynamic control are fired AFTER the page's Load and button's AjaxEvent are fired. I am adding the dynamic controls during Page Init. With standard ASP.NET, dynamic controls should play catch up as soon as they are added to the page.

Here's a small code example. Make sure to run this in debug mode and just pay attention to the order of events during the tool button click.

ASPX:


<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="DynamicControls.aspx.vb"
Inherits="Coolite.DynamicControls" %>

<%@ Register Assembly="Coolite.Ext.Web" Namespace="Coolite.Ext.Web" TagPrefix="ext" %>
<!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></title>
</head>
<body>
<form id="form1" runat="server">
<script runat="server">

</script>
<ext:ScriptManager ID="ScriptManager1" runat="server">
</ext:ScriptManager>
<ext:Panel runat="server" ID="pnlExt" Title="Dynamic Control Test">
<TopBar>
<ext:Toolbar runat="server">
<Items>
<ext:ToolbarButton runat="server" ID="btnTest" Text="Test">
<AjaxEvents>
<Click OnEvent="btnClicked">
<EventMask ShowMask="true" Msg="Working..." />
</Click>
</AjaxEvents>
</ext:ToolbarButton>
</Items>
</ext:Toolbar>
</TopBar>
<Body>
<ext:FormLayout runat="server" ID="pnlForm">
</ext:FormLayout>
</Body>
</ext:Panel>
</form>
</body>
</html>


VB


Imports Coolite.Ext.Web

Partial Public Class DynamicControls
Inherits System.Web.UI.Page

Private Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
Dim newAnchor As New Anchor
Me.pnlForm.Anchors.Add(newAnchor)

Dim pnl As New Panel()
newAnchor.Items.Add(pnl)

pnl.BodyControls.Add(New DummyControl)

If Debugger.IsAttached Then Debugger.Break()
End Sub

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Debugger.IsAttached Then Debugger.Break()
End Sub

Protected Sub btnClicked(ByVal sender As Object, ByVal e As AjaxEventArgs)
If Debugger.IsAttached Then Debugger.Break()
End Sub

End Class

Public Class DummyControl
Inherits Control
Implements IPostBackDataHandler

Private Sub Dummy_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
If Debugger.IsAttached Then Debugger.Break()
End Sub

Private Sub Dummy_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Debugger.IsAttached Then Debugger.Break()
End Sub

Public Function LoadPostData(ByVal postDataKey As String, ByVal postCollection As System.Collections.Specialized.NameValueCollection ) As Boolean Implements System.Web.UI.IPostBackDataHandler.LoadPostData
If Debugger.IsAttached Then Debugger.Break()
End Function

Public Sub RaisePostDataChangedEvent() Implements System.Web.UI.IPostBackDataHandler.RaisePostDataCh angedEvent
If Debugger.IsAttached Then Debugger.Break()
End Sub

End Class

Vladimir
Nov 04, 2008, 12:18 AM
Hi jchau,

I made some changes in the AnchorLayout.

Can you update from SVN and test again?

Thanks in advance

jchau
Nov 04, 2008, 1:19 AM
Same example now throws a RTE in AnchorLayout.cs



System.ArgumentOutOfRangeException was unhandled by user code
Message="Index was out of range. Must be non-negative and less than the size of the collection.\r\nParameter name: index"
Source="mscorlib"
ParamName="index"
StackTrace:
at System.ThrowHelper.ThrowArgumentOutOfRangeExceptio n(ExceptionArgument argument, ExceptionResource resource)
at System.ThrowHelper.ThrowArgumentOutOfRangeExceptio n()
at System.Collections.Generic.List`1.get_Item(Int32 index)
at Coolite.Ext.Web.AnchorLayout.Anchors_AfterItemAdd( Anchor item) in C:\Program Files\Coolite\SVN\toolkit\Coolite.Ext.Web\Ext\Layo ut\AnchorLayout.cs:line 97
at Coolite.Ext.Web.StateManagedCollection`1.Add(T item) in C:\Program Files\Coolite\SVN\toolkit\Coolite.Ext.Web\Utility\ StateManagedCollection.cs:line 92
at Coolite.DynamicControls.Page_Init(Object sender, EventArgs e) in C:\Documents and Settings\jchau\My Documents\Visual Studio 2008\Projects\Coolite\DynamicControls.aspx.vb:line 8
at System.Web.UI.Control.OnInit(EventArgs e)
at System.Web.UI.Page.OnInit(EventArgs e)
at System.Web.UI.Control.InitRecursive(Control namingContainer)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
InnerException:


Looks like item.Items.Count is 0 for my case. I modified my example to add the panel to the anchor first before adding the anchor to the formlayout. That fixed the RTE, but that should probably be handled by the Toolkit. Also, LoadPostData is still not firing on the dynamic DummyControl. However, I think that's an ASP.NET flaw and not Coolite related.


void Anchors_AfterItemAdd(Anchor item)

{

item.Items[0].AdditionalConfig = item;

this.Items.Add((Component)item.Control);

}


Thanks vladimir for quick response!!

jchau
Nov 04, 2008, 1:23 AM
Ignore my comment on LoadPostData. My DummyControl is too dumb to be properly registered to receive postdata =P.

geoffrey.mcgill
Nov 04, 2008, 9:52 AM
Hi jchau,

We adjusted a few things within the control Lifecycle and I think things should be working much better now. Please SVN update and retest. 


This was only a problem with the AnchorLayout and FormLayout controls. I'm doing some more testing with the other Layout controls to ensure the defects were fixed in all.


Hope this helps.