[CLOSED] Loading userControls dinamically inside tabs

  1. #1

    [CLOSED] Loading userControls dinamically inside tabs

    Hi,
    Due to the size of our forms, we have performance problems. Many tabs with fields in each.
    Structurally we divided each tab in usercontrols to keep the code more organized.
    We are trying to load tabs dynamically, but we have some difficulties and we would like you to help and tell us what is the best way to do this.

    When performing a call directevent we received an error that the control was not found. We know that this is because the dynamically created controls must be recreated to each request. But how would we do this keeping the states of the controls?

    We are using version 1.6 of Ext.NET and if necessary we can upgrade to version 2.1.

    In this example we need to load the usercontrols of the tabs and send/filter data to the server side keeping the state/data on screen.

    BaseUserControl
    using System.Collections.Generic;
    using System.Web.UI;
    
    
        public class BaseUserControl : UserControl
        {
            public virtual List<string> ControlsToDestroy
            {
                get
                {
                    // we should return none lazy controls only because lazy controls will be autodestroyed by parent container
                    return new List<string>();
                }
            }
    
            public virtual void LoadData()
            {
                        
            }
        }
    Default.aspx
    <%@ Page Language="C#" AutoEventWireup="true" Inherits="System.Web.UI.Page" %>
    
    <script runat="server">
    
        public bool ControlGenerated
        {
            get
            {
                var viewstate = ViewState["ControlGenerated"];
                return viewstate != null ? (bool)viewstate : false;
            }
            set { ViewState["ControlGenerated"] = value; }
        }
    
        protected void Page_Load(object sender, EventArgs e)
        {
        }
    
        protected void FormTab_Activate(object sender, DirectEventArgs e)
        {
            var controlName = e.ExtraParams["controlName"].ToString();
            var control = e.ExtraParams["control"].ToString();
            var panel = (Ext.Net.Panel)sender;
    
            CreateControl(control, controlName, panel);
        }
    
        private void CreateControl(string userControl, string controlName, Ext.Net.Panel panel)
        {
            X.Js.Call("destroyFromCache", new JRawValue(panel.ClientID));
            var control = (BaseUserControl)this.LoadControl(userControl);
            control.ID = controlName;
            panel.ContentControls.Add(control);
            control.LoadData();
            X.Js.Call("putToCache", new JRawValue(panel.ClientID), control.ControlsToDestroy);
            panel.UpdateContent();
        }
    
    
    </script>
    
    <!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 id="Head1" runat="server">
        <title>Ext.NET Example</title>
    
        <script type="text/javascript">
            var destroyFromCache = function (container) {
                container.controlsCache = container.controlsCache || [];
                Ext.each(container.controlsCache, function (controlId) {
                    var control = Ext.getCmp(controlId);
                    if (control && control.destroy) {
                        control.destroy();
                    }
                });
            };
    
            var putToCache = function (container, controls) {
                container.controlsCache = controls;
            };
        </script>
    
    </head>
    <body>
        <form id="Form1" runat="server">
            <ext:ResourceManager runat="server" />
    
            <a href="http://www.ext.net/">
                <img src="http://speed.ext.net/identity/extnet-logo-small.png" /></a>
    
            <ext:Container ID="MainContainer" runat="server">
            </ext:Container>
    
            <ext:TabPanel runat="server" Height="350">
                <Items>
                    <ext:Panel ID="MainTabPanel" runat="server" Title="Main">
                    </ext:Panel>
                    <ext:Panel ID="FormTabPanel" runat="server" Title="Form">
                        <DirectEvents>
                            <Activate OnEvent="FormTab_Activate" Single="true">
                                <ExtraParams>
                                    <ext:Parameter Name="control" Value="~/UserWebUserControl.ascx"></ext:Parameter>
                                    <ext:Parameter Name="controlName" Value="userWebUserControl"></ext:Parameter>
                                </ExtraParams>
                            </Activate>
                        </DirectEvents>
                    </ext:Panel>
                    <ext:Panel ID="GridTabPanel" runat="server" Title="Grid">
                        <DirectEvents>
                            <Activate OnEvent="FormTab_Activate" Single="true">
                                <ExtraParams>
                                    <ext:Parameter Name="control" Value="~/UserGridWebUserControl.ascx"></ext:Parameter>
                                    <ext:Parameter Name="controlName" Value="userGridWebUserControl"></ext:Parameter>
                                </ExtraParams>
                            </Activate>
                        </DirectEvents>
                    </ext:Panel>
                </Items>
            </ext:TabPanel>
    
        </form>
    </body>
    </html>
    UserGridWebUserControl.ascx
    <%@ Control Language="C#" AutoEventWireup="true" Inherits="BaseUserControl" %>
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
    
        }
    
        public override List<string> ControlsToDestroy
        {
            get
            {
                // we should return none lazy controls only because lazy controls will be autodestroyed by parent container
                return new List<string>
                           {
                                GridPanelControl.ClientID,
                           };
            }
        }
    
        public override void LoadData()
        {
            LoadGridData(searchField.Text);
        }
    
        [DirectMethod]
        public void LoadGridData(string data)
        {
            var list = new List<TestClass>();
    
            for (int i = 1; i < 11; i++)
            {
                var test = new TestClass
                {
                    Id = i,
                    Nome = string.Format("Nome {0}", i),
                    DataInicial = DateTime.Now,
                    DataFinal = DateTime.Now
                };
                list.Add(test);
            }
    
            if (!string.IsNullOrEmpty(data))
                list = list.Where(i => i.Nome.Contains(data)).ToList();
    
            GridPanelControlStore.DataSource = list;
            GridPanelControlStore.DataBind();
        }
    
        protected void searchButton_DirectClick(object sender, DirectEventArgs e)
        {
            //LoadGridData(searchField.Text);
        }
    
        protected void GridPanelControlStore_RefreshData(object sender, StoreRefreshDataEventArgs e)
        {
            LoadGridData(searchField.Text);
        }
    
        protected void GridCommand_Event(object sender, DirectEventArgs e)
        {
            var nome = e.ExtraParams["nome"].ToString();
            X.Msg.Notify("Nome", nome).Show();
        }
    
        public class TestClass
        {
            public int Id { get; set; }
            public string Nome { get; set; }
            public DateTime DataInicial { get; set; }
            public DateTime DataFinal { get; set; }
        }    
    
    </script>
    
    <ext:GridPanel ID="GridPanelControl" runat="server" AutoExpandColumn="Nome" StripeRows="true" Border="false">
        <TopBar>
            <ext:Toolbar runat="server">
                <Items>
                    <ext:TextField ID="searchField" runat="server"></ext:TextField>
                    <ext:Button ID="searchButton" runat="server" Text="OK">
                        <Listeners>
                            <Click Handler="#{GridPanelControl}.store.reload();" />
                        </Listeners>
                    </ext:Button>
                </Items>
            </ext:Toolbar>
        </TopBar>
        <Store>
            <ext:Store ID="GridPanelControlStore" runat="server" OnRefreshData="GridPanelControlStore_RefreshData">
                <Reader>
                    <ext:JsonReader IDProperty="Id">
                        <Fields>
                            <ext:RecordField Type="Int" Name="Id"></ext:RecordField>
                            <ext:RecordField Type="String" Name="Nome"></ext:RecordField>
                            <ext:RecordField Type="Date" Name="DataInicial"></ext:RecordField>
                            <ext:RecordField Type="Date" Name="DataFinal"></ext:RecordField>
                        </Fields>
                    </ext:JsonReader>
                </Reader>
            </ext:Store>
        </Store>
        <ColumnModel>
            <Columns>
                <ext:CommandColumn Width="60">
                    <Commands>
                        <ext:GridCommand Icon="Delete" CommandName="Delete">
                            <ToolTip Text="Delete" />
                        </ext:GridCommand>
                        <ext:CommandSeparator />
                        <ext:GridCommand Icon="NoteEdit" CommandName="Edit">
                            <ToolTip Text="Edit" />
                        </ext:GridCommand>
                    </Commands>
                </ext:CommandColumn>
                <ext:Column DataIndex="Id" ColumnID="Id" Header="Id"></ext:Column>
                <ext:Column DataIndex="Nome" ColumnID="Nome" Header="Nome"></ext:Column>
                <ext:DateColumn DataIndex="DataInicial" ColumnID="DataInicial" Header="Data Inicial" Format="dd/MM/yyyy"></ext:DateColumn>
                <ext:DateColumn DataIndex="DataFinal" ColumnID="DataFinal" Header="Data Final" Format="dd/MM/yyyy"></ext:DateColumn>
            </Columns>
        </ColumnModel>
        <SelectionModel>
            <ext:RowSelectionModel runat="server" SingleSelect="true"></ext:RowSelectionModel>
        </SelectionModel>
        <BottomBar>
            <ext:PagingToolbar runat="server"></ext:PagingToolbar>
        </BottomBar>
        <DirectEvents>
            <Command OnEvent="GridCommand_Event">
                <ExtraParams>
                    <ext:Parameter Name="nome" Value="record.data.Nome"></ext:Parameter>
                </ExtraParams>
            </Command>
        </DirectEvents>
    </ext:GridPanel>
    UserWebUserControl.ascx
    <%@ Control Language="C#" AutoEventWireup="true" Inherits="BaseUserControl" %>
    
    <script runat="server">
    
        protected void Page_Load(object sender, EventArgs e)
        {
    
        }
    
        protected void Salvar_Click(object sender, DirectEventArgs e)
        {
            X.Msg.Notify("Message", this.Nome.Text).Show();
        }
    
        public override List<string> ControlsToDestroy
        {
            get
            {
                // we should return none lazy controls only because lazy controls will be autodestroyed by parent container
                return new List<string>
                           {
                                PanelControl.ClientID,
                           };
            }
        }
    
    </script>
    
    
    <ext:Panel
        ID="PanelControl"
        runat="server"   
        Padding="5"
        Layout="FormLayout"
        Border="false"
        Width="600"
        DefaultAnchor="100%">
        <Items>
            <ext:TextField ID="Nome" runat="server" FieldLabel="Nome" />
            <ext:DateField ID="DataInicial" runat="server" FieldLabel="Data Inicial"/>
            <ext:DateField ID="DataFinal" runat="server" FieldLabel="Data Final"/>
        </Items>
        <Buttons>
            <ext:Button ID="Salvar" runat="server" Text="Salvar" OnDirectClick="Salvar_Click">
            </ext:Button>
    
        </Buttons>
    </ext:Panel>
    Thank you.
    Last edited by Daniil; Jan 11, 2013 at 4:40 AM. Reason: [CLOSED]
  2. #2
    Hi Rogerio,

    Personally, I would use a combination of client side listeners and DirectMethods instead of DirectEvents.

    You can send any required data as parameters.

    This way you will avoid a needing to recreate controls.

    You will be able to put logic into a WebService or an HTTP handler and refer it by its URL. It is possible with the both approaches - DirectMethods and DirectEvents. In this case you would avoid recreating a page control itself and, respectively, it would improve the performance as well.

    Re: upgrading to Ext.NET v2

    Well, it is a separate task. There are many breaking changes. And, generally, there is nothing new in this aspect.
  3. #3
    Hello Daniil, thanks for your reply.

    We had already thought of this possibility to change the system for the customer, but as the system is already in the final stages of construction this change becomes unfeasible at this time.
    We are using ASP.NET webforms style and some things in the system using direct methods and custom scripts and now we are suffering with system performance because the size and quantity of controls on a single form.
    Recreate the controls is not the problem, but keep your system running as it is today, loading usercontrols dynamically to avoid everything to be loaded at the beginning unnecessarily.
    The examples provided for loading usercontrols are very simple, and we do not find something that would help us in the forum.

    If you need more details of our project we are available.

    Thank you.
  4. #4
    Well, if you can't change the design, then, as you correctly mentioned, you should recreate the controls to get DirectEvents working.

    But how would we do this keeping the states of the controls?
    The submittable things will be posted back to a server.

    ViewState can help as well.

    The two links in this post might be helpful.
    http://forums.ext.net/showthread.php...ll=1#post60155

Similar Threads

  1. Replies: 4
    Last Post: Feb 01, 2012, 9:37 AM
  2. Replies: 7
    Last Post: Oct 28, 2011, 5:25 PM
  3. Replies: 3
    Last Post: Sep 15, 2010, 9:29 PM
  4. [CLOSED] Multiple UserControls, Column and Tabs
    By CMA in forum 1.x Premium Help
    Replies: 5
    Last Post: Jan 15, 2010, 1:09 PM
  5. [CLOSED] Help with grids in codebehind inside tabs
    By jcanton in forum 1.x Premium Help
    Replies: 4
    Last Post: May 29, 2009, 11:33 AM

Tags for this Thread

Posting Permissions