[CLOSED] Dynamic user control pattern and access to server side controls values

  1. #1

    [CLOSED] Dynamic user control pattern and access to server side controls values

    Hi,

    I am experiencing odd behavior. When DirectMethod (in case of my project) or DirectEvent (I have reproduced the problem based on UserControl pattern presented in this example https://examples3.ext.net/#/XRender/...UpdateContent/) load user control dynamically check-box selection is not updated on server side.

    Let's start with example code where you can reproduce the problem: 4 files (like it the example above)


    Default.aspx

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Collections.Generic"%>
    
    <script runat="server">
        UserControl currentUC;
        
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(CurrentControl.Text))
            {
                this.LoadUserControl(CurrentControl.Text);
            }
    
            //// (UN)COMMENT THIS LATER
            //else
            //{
            //    this.LoadUserControl("1");
            //}
        }
    
        private void LoadUserControl(string num, bool update = false)
        {
            if (update && currentUC != null)
            {            
                this.Panel1.ContentControls.Clear();
            }        
            
            currentUC = (UserControl)this.LoadControl(string.Format("UserControl{0}.ascx", num));
            currentUC.ID = "UC" + num;
            this.Panel1.ContentControls.Add(currentUC);
            
            if (update)
            {
                CurrentControl.Text = num;
                this.Panel1.UpdateContent();
            }
        }
    
        protected void Button1_Click(object sender, DirectEventArgs e)
        {
            this.LoadUserControl("1", true);
            
            this.Button1.Disabled = true;
            this.Button2.Disabled = false;
        }
    
        protected void Button2_Click(object sender, DirectEventArgs e)
        {
            this.LoadUserControl("2", true);
    
            this.Button2.Disabled = true;
            this.Button1.Disabled = false;
        }
    </script>
    
    <!DOCTYPE html>
    
    <html>
    <head runat="server">
        <title>Update Controls and Content during a DirectEvent - Ext.NET Examples</title>
        <link href="/resources/css/examples.css" rel="stylesheet" />
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
            
            <h1>Update Controls and Content during a DirectEvent</h1>
            
            <h3>Load UserControls</h3>
            
            <ext:Hidden ID="CurrentControl" runat="server" />
    
            <ext:Panel 
                ID="Panel1" 
                runat="server" 
                Title="User Controls" 
                Width="800" 
                Height="800"
                BodyPadding="10">
                <TopBar>
                    <ext:Toolbar runat="server">
                        <Items>
                            <ext:Button 
                                ID="Button1" 
                                runat="server" 
                                Text="Load 1"
                                
                                OnDirectClick="Button1_Click" 
                                />
                            <ext:Button 
                                ID="Button2" 
                                runat="server" 
                                Text="Load 2" 
                                Disabled="true"
                                OnDirectClick="Button2_Click"                            
                                />
                        </Items>
                    </ext:Toolbar>
                </TopBar>
            </ext:Panel>
        </form>
    </body>
    </html>





    UserControl1.ascx

    <%@ Control Language="C#" %>
    <script runat="server">
    
        protected void Page_Load(object sender, EventArgs e)
        {
            ResourceManager.RegisterGlobalScript("script.js");
        }   
    
        protected void HelloFromServer(object sender, DirectEventArgs e)
        {
            X.Msg.Alert("Server", "Hello from server - UserControl #1").Show();
            CheckboxSelectionModel selection = this.UploadGrid.GetSelectionModel() as CheckboxSelectionModel;
    
        
            X.Msg.Alert("Server", selection.SelectedRows.Count.ToString()).Show();
        }        
    
        protected void onDeleteFiles(object sender, DirectEventArgs e)
        {
            CheckboxSelectionModel selection = this.UploadGrid.GetSelectionModel() as CheckboxSelectionModel;
        
            X.Msg.Alert("Server", selection.SelectedRows.Count.ToString()).Show();
        }
        
    
    </script>
    
    <h1>#1</h1>
    
    <ext:Label runat="server" Text="I am User control #1" />
    
    <br /><br />
    
    <ext:GridPanel
        ID="UploadGrid"
        runat="server"
        Border="false"
        Frame="false">
        <Store>
            <ext:Store runat="server">
                <Model>
                    <ext:Model 
                        runat="server" 
                        IDProperty="id">
                        <Fields>
                            <ext:ModelField Name="id" />
                            <ext:ModelField Name="name" />
                        </Fields>
                    </ext:Model>
                </Model>
            </ext:Store>
        </Store>
        <ColumnModel>
            <Columns>
                <ext:Column
                    runat="server"
                    Text="Name"
                    DataIndex="name"
                    Width="200"
                    MenuDisabled="true"
                    Flex="1" />
            </Columns>
        </ColumnModel>
        <TopBar>
            <ext:Toolbar Frame="false" runat="server">
                <Items>
                    <ext:Button
                        runat="server"
                        Text="Add File"
                        Handler="#{UploadGrid}.store.add({id: Ext.id(), name: Ext.id() });" />
    
                    <ext:ToolbarSeparator />
                    
                    <ext:Button
                        ID="btnDeleteFiles"
                        runat="server"
                        Text="Delete Files"
                        OnDirectClick="onDeleteFiles" />
                </Items>
            </ext:Toolbar>
        </TopBar>
    
        <SelectionModel>
            <ext:CheckboxSelectionModel
                ID="selUploads"
                runat="server"
                Mode="Multi"
                CheckOnly="true">
            </ext:CheckboxSelectionModel>
        </SelectionModel>
    </ext:GridPanel>
    
    
    <ext:Button 
        ID="Button1"
        runat="server" 
        Text="User control #1: Ext.Net button" 
        OnDirectClick="HelloFromServer" />
    
    <br />
    
    <asp:Button 
        runat="server" 
        Text="User control #1: ASP.NET button" 
        OnClientClick="helloFromClient('UserControl #1'); return false;" />


    UserControl2.ascx


    <%@ Control Language="C#" %>
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            ResourceManager.RegisterGlobalScript("script.js");
        }   
    
        protected void HelloFromServer(object sender, DirectEventArgs e)
        {
            X.Msg.Alert("Server", "Hello from server - UserControl #2").Show();
        }        
    </script>
    
    <h1>#2</h1>
    
    <ext:Label runat="server" Text="I am User control #2" />
    
    <br /><br />
    
    <ext:Button 
        ID="Button1"
        runat="server" 
        Text="User control #2: Ext.Net button" 
        OnDirectClick="HelloFromServer" />
    
    <br />
    
    <asp:Button 
        runat="server" 
        Text="User control #2: ASP.NET button" 
        OnClientClick="helloFromClient('UserControl #2'); return false;" />


    script.js

    function helloFromClient (id) {
        Ext.Msg.alert("Client", "Hello from client - " + id);
    }



    Reproduce the problem:

    1. Click "Load 1"
    2. Click "Add File"
    3. Check/Tick added file(s)
    4. Click "Delete Files"

    The message will show selected row count = "0" ... The request parameters are not applied in server side control.


    Reproduce desired behavior: (it is not a solution)


    1. Uncomment part of the code in Page_Load of Default.aspx - this will cause that UserControl1 will be loaded straightaway.
    2. Click "Add File"
    3. Check/Tick added file(s)
    4. Click "Delete Files"



    The message will show all selected/ticked row count;


    I have looked in HttpRequest params and I can see the selection being sent to the server in every request but without loading the control in first OnLoad the selection is not applied into (re)loaded control:

    __EVENTTARGET=ctl04
    __EVENTARGUMENT=UC1_btnDeleteFiles%7Cevent%7CClick
    __VIEWSTATE=%2FwEPDwUKLTM0MjE0NDg2MGQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgUFBWN0bDA0BQ5DdXJyZW50Q29udHJvbAUGUGFuZWwxBQdCdXR0b24xBQdCdXR0b24ybm4I5DTssbFcAbdmKNpVhD3X6OY%3D
    __VIEWSTATEGENERATOR=CA0B0334
    __EVENTVALIDATION=%2FwEdAAJx0HpVqZ04x1H8TqhxWcixIF3M%2BHYlKCbBj3zl7ccu778Oo348HOClMjfwYgtwNA%2FS55NS
    CurrentControl=1
    UC1_selUploads=%5B%7B%22RecordID%22%3A%22ext-68%22%2C%22RowIndex%22%3A0%7D%2C%7B%22RecordID%22%3A%22ext-70%22%2C%22RowIndex%22%3A1%7D%2C%7B%22RecordID%22%3A%22ext-72%22%2C%22RowIndex%22%3A2%7D%2C%7B%22RecordID%22%3A%22ext-74%22%2C%22RowIndex%22%3A3%7D%5D


    Thank you,
    Last edited by Daniil; Mar 22, 2015 at 7:13 PM. Reason: [CLOSED]
  2. #2
    Hi Matt,

    The user control is recreated in Page_Load and it is too late for a LoadPostData call on that control.

    Please change Page_Load to Page_Init. In this case CurrentControl.Text will stop working, because it is too early for a LoadPostData:) A possible solution is Session:

    protected void Page_Init(object sender, EventArgs e)
    {
        string num = this.Session["CurrentControl"] as string;
    
        if (!string.IsNullOrWhiteSpace(num))
        {
            this.LoadUserControl(num);
        }
    }
    and replacing
    CurrentControl.Text = num;
    with
    this.Session["CurrentControl"] = num;
    in the LoadUserControl method.
  3. #3
    Hi Danill,

    Awesome! I was aware about UserControl recreation requirement but was "fighting" around OnLoad for hours :)
    Until now all my direct events and direct methods were working fine until I needed to access the controls properties within my user control.

    Thank you very much ! I should have ask about it earlier, but always trying to research the problem as much as I can first.

    Have a great weekend,
  4. #4

    Request parameter instead Session

    I'd like to add something for anyone looking for similar solution...

    In my project I allow user to have multiple windows (tabs) with different views within the same session. Using Session["CurrentControl"] directly was not an option for me because I implemented my own session manager (a wrapper) that allow to store and manage my session objects for multiple browser tabs/windows.


    The hidden "CurrentControl" element is a part of <form> so it's value is being send with every request.

    We can use it this way:

        protected void Page_Init(object sender, EventArgs e)
        {
            string num = HttpContext.Current.Request.Params["CurrentControl"] as string;
    
            if (!string.IsNullOrWhiteSpace(num))
            {
                this.LoadUserControl(num);
            }
        }

    Hope this will be helpful too...

    Thanks,
    Last edited by Daniil; Mar 22, 2015 at 7:00 PM.
  5. #5
    Glad to help you and thanks for sharing your valuable comments!
  6. #6
    From MCTS Self-Placed Traning kit Exam 70-562
    Click image for larger version. 

Name:	lc001.png 
Views:	4 
Size:	20.5 KB 
ID:	22901

    Click image for larger version. 

Name:	lc002.png 
Views:	5 
Size:	24.6 KB 
ID:	22911

    Click image for larger version. 

Name:	lc003.png 
Views:	4 
Size:	41.3 KB 
ID:	22921
  7. #7
    Thank you, Raphael!

    I see the PreInit event is recommended for creating dynamic controls.
  8. #8
    The following book is very interesting, no matter if you want to take 70-562 exam or just want to improve your knowledge: http://www.amazon.com/MCTS-Self-Pace.../dp/073562562X

Similar Threads

  1. Replies: 1
    Last Post: Jan 26, 2015, 3:42 PM
  2. [CLOSED] gridpanel: access to cell values server side
    By marco.morreale in forum 2.x Legacy Premium Help
    Replies: 1
    Last Post: Nov 26, 2014, 7:12 PM
  3. [CLOSED] Server side controls values with DirectEvent calls
    By Daniil in forum 1.x Legacy Premium Help
    Replies: 3
    Last Post: Feb 10, 2012, 11:52 AM
  4. Replies: 6
    Last Post: Jul 28, 2011, 4:43 PM

Tags for this Thread

Posting Permissions