Bug with dynamic panels and slider control

  1. #1

    Bug with dynamic panels and slider control

    Hello All,

    I think that i found another bug ( or two may be ) with my current project.
    I'm using only dynamic creation of controls, so may be this is not usual task and i found some problems.
    Currently i will show bug with siled panel. When i create panel dynamicaly, and add to this panel slider control,
    during post backs, control dont have propper value.
    Here is a code :

    File : Default.aspx


    %@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication2._Default" %>
    <%@ Register assembly="Ext.Net" namespace="Ext.Net" 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">
    </head>
    <body>
    <form id="form1"  runat="server">
        <ext:ResourceManager runat="server" ID="resman" DirectMethodNamespace="DM"/>
        <ext:Viewport runat="server" ID="id_viewport">
                <Items>
                    <ext:Panel runat="server">
                        <TopBar>
                            <ext:Toolbar runat="server">
                                <Items>
                                    <ext:Button runat="server" ID="Button1" Text="Panel 1"></ext:Button>
                                    <ext:Button runat="server" ID="Button2" Text="Panel 2"></ext:Button>
                                </Items>
                            </ext:Toolbar>
                        </TopBar>
                        <Items>
                            <ext:Panel runat="server" id="id_container" Title="Main panel" >
                            </ext:Panel>
                        </Items>
                    </ext:Panel>
                </Items>
            </ext:Viewport>
    </form>
    </body>
    </html>
    File : Default.aspx.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Ext.Net;
    
    namespace WebApplication2
    {
        public class PanelType1 : Ext.Net.Panel
        {
            public PanelType1()
            {
                this.ID = "id_paneltype_1";
                this.Height = 600;
                this.Layout = "Absolute";
                this.Title = "Panel Type 1" + " ( Updated on  " + DateTime.Now + " )";
    
                this.Html = "Panel from type 1";
            }
    
        }
    
        public class PanelType2 : Ext.Net.Panel
        {
            Ext.Net.Slider sldAudioOff;
            Ext.Net.TextField fldValue;
            Ext.Net.Label fldUpdateTime;
            Ext.Net.Label fldLabel;
            public PanelType2()
            {
                this.ID = "id_paneltype_2";
                this.Title = "Panel Type 2" + " ( Updated on  " + DateTime.Now + " )";
                this.Height = 600;
                this.Layout = "Absolute";
    
                sldAudioOff     = new Ext.Net.Slider    { ID = "id_audioSlide", X = 5,   Y = 10, Width = 200, MinValue = -10, MaxValue = 10, Value = 0 };
                fldLabel        = new Ext.Net.Label     { ID = "id_val_label1", X = 215, Y = 10, Text = "Value of slider" };
                fldValue        = new Ext.Net.TextField { ID = "id_text_fld"  , X = 310, Y = 10, Width = 40, Text = sldAudioOff.Value.ToString() };
                fldUpdateTime   = new Ext.Net.Label     { ID = "id_val_label2", X = 360, Y = 10, Text = "" };
    
                sldAudioOff.DirectEvents.ChangeComplete.Event += this.AudioSliderValueChange;
    
                this.Add(sldAudioOff);
                this.Add(fldLabel);
                this.Add(fldValue);
                this.Add(fldUpdateTime);
            }
    
    
            public void AudioSliderValueChange(object sender, DirectEventArgs args)
            {
                fldValue.Text = sldAudioOff.Value.ToString();
                fldUpdateTime.Text = "Updated on  " + DateTime.Now;
            }
    
        }
    
        public partial class _Default : System.Web.UI.Page
        {
            public static int showtype=1;
    
            protected override void OnInit(EventArgs e)
            {
                Button1.DirectEvents.Click.Event += AddNewPanel_1;
                Button2.DirectEvents.Click.Event += AddNewPanel_2;
    
                AddPanel(false);
    
                base.OnInit(e);
            }
    
            protected void RemoveCurrentPanel()
            {
                Ext.Net.Panel p1 = (Ext.Net.Panel)id_container.Items[0];
                id_container.Remove(p1, true);
                id_container.DoLayout();
            }
    
            protected void AddNewPanel_1(object sender, DirectEventArgs e)
            {
                showtype = 1;
                RemoveCurrentPanel();
                AddPanel();
            }
    
            
            protected void AddNewPanel_2(object sender, DirectEventArgs e)
            {
                showtype = 2;
                RemoveCurrentPanel();
                AddPanel();
            }
    
    
            public void AddPanel(bool DoRendering = true)
            {
    
                if (showtype == 1)
                {
                    PanelType1 panel = new PanelType1();
                    id_container.Items.Add(panel);
                    if (DoRendering)
                        panel.Render();
                }
                else if (showtype == 2)
                {
                    PanelType2 panel = new PanelType2();
                    id_container.Items.Add(panel);
                    if (DoRendering)
                        panel.Render();
                }
    
                id_container.DoLayout();
            }
    
        }
    }
    Bug can be reproduced in this way : when app stars, click on button "Panel 2". Second panel will be displayed.
    Then moving of slider cause execution of direct event handler AudioSliderValueChange. In this function we read value
    of slider control and show this value in fldValue control, plus we add timestamp when value is updated.
    As you can see - moving of slider doesent affect of control value.

    I think that its important to say, if Panel2 is created first , all works ok. But if we create first panel1 , and then
    create Panel 2 with clicking of button - control not work on propper way.
    This also can be reproduced easy - start application, click on button Panel 2, then stop and start again application from Visual Studio.
    Then Panel 2 first will be displayed. Moving of slider works ok.

    This is a one think. Another that i see is that in constructor of class PanelType2, i have code for putting of timestamp
    in title :
    this.Title = "Panel Type 2" + " ( Updated on  " + DateTime.Now + " )";
    Problem is that, even we pass trough constructor, title of pannel is not changed.

    I found another bug with grid panels, but will put in separate thread :)


    Regards,
    Nedelcho
  2. #2
    It's not a bug guys? :)
  3. #3
    You have to enable ViewState transfer for Button1 and Button2 direct events otherwise ASP.NET will not call LoadPostData method for dynamic controls
    Button1.DirectEvents.Click.Event += AddNewPanel_1;
                Button1.DirectEvents.Click.ViewStateMode = ViewStateMode.Enabled;
                Button2.DirectEvents.Click.Event += AddNewPanel_2;
                Button2.DirectEvents.Click.ViewStateMode = ViewStateMode.Enabled;
  4. #4
    But, its works for text fields for example without setting ViewStateMode?
    And this is necessary only for sliders or for other controls too?
    Can you specify for which this need to be done?
  5. #5
    I've gone through your original code sample in detail. There are/were several issues.

    First off, here's a revised and simplified sample demonstrating a full working scenario of dynamic Control creation during a DirectEvent.

    Example

    <%@ Page Language="C#" %>
    
    <%@ Import Namespace="Panel=Ext.Net.Panel" %>
    <%@ Import Namespace="Label=Ext.Net.Label" %>
    
    
    <%@ Register assembly="Ext.Net" namespace="Ext.Net" tagprefix="ext" %>
    
    
    <script runat="server">
        protected override void OnInit(EventArgs e)
        {
            this.Button1.DirectEvents.Click.Event += Button1_Click;
            this.Button2.DirectEvents.Click.Event += Button2_Click;
    
    
            // If initial Page_Load, then just add a "MyPanel" Component. 
            // Ignore for DirectEvent/DirectMethod requests. 
            if (!X.IsAjaxRequest)
            {
                this.Panel1.Items.Add(new MyPanel());
            }
            
            base.OnInit(e);
        }
    
    
        protected void Button1_Click(object sender, DirectEventArgs e)
        {
            this.Panel1.RemoveAll();
            new MyPanel().AddTo(this.Panel1);
        }
    
    
        protected void Button2_Click(object sender, DirectEventArgs e)
        {
            this.Panel1.RemoveAll();
            new AnotherPanel().AddTo(this.Panel1);
        }
    
    
        public class MyPanel : Panel
        {
            public MyPanel()
            {
                this.ID = "MyPanel1";
                this.Layout = "Absolute";
                this.Title = "MyPanel" + " (Updated : " + DateTime.Now + ")";
    
    
                this.Padding = 5;
                this.Html = "MyPanel";
            }
        }
    
    
        public class AnotherPanel : Panel
        {
            Slider slider1;
            Label label1;
    
    
            public AnotherPanel()
            {
                this.ID = "AnotherPanel1";
                this.Title = "AnotherPanel" + " (Updated : " + DateTime.Now + ")";
                this.Layout = "Absolute";
                this.Padding = 5;
    
    
                this.slider1 = new Slider
                {
                    ID = "Slider1",
                    X = 5,
                    Y = 10,
                    Width = 200,
                    MinValue = -10,
                    MaxValue = 10,
                    Value = 0
                };
    
    
                this.label1 = new Label
                {
                    ID = "Label1",
                    X = 215,
                    Y = 10
                };
    
    
                this.slider1.Listeners.ChangeComplete.Handler = "CompanyX.Update();";
     
                this.Add(this.slider1);
                this.Add(this.label1);
            }
        }
    
    
        [DirectMethod]
        public void Update()
        {
            // Gets the raw "Slider1_Value" from the Request object.
            var sliderValue = X.GetValue("Slider1_Value");
    
    
            X.Msg.Notify("Slider Value", sliderValue).Show();
            X.GetCmp<Label>("Label1").Text = "Updated on  " + DateTime.Now;
        }
    </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 runat="server">
        <title>Ext.NET Example</title>
    </head>
    <body>
    <form runat="server">
        <ext:ResourceManager runat="server" DirectMethodNamespace="CompanyX" />
    
    
        <ext:Panel id="Panel1" runat="server" Height="215" Layout="FitLayout" Border="false">
            <TopBar>
                <ext:Toolbar runat="server">
                    <Items>
                        <ext:Button ID="Button1" runat="server" Text="Panel 1" />
                        <ext:Button ID="Button2" runat="server" Text="Panel 2" />
                    </Items>
                </ext:Toolbar>
            </TopBar>
        </ext:Panel>
    </form>
    </body>
    </html>
    It's going to be a challenge to explain all the changes required and why they're required, but I'll give it a shot over the following posts.
    Geoffrey McGill
    Founder
  6. #6
    Hello,

    And first thanks for the answer :)
    This works ok yes, but as i understand, in this way, directevents cannot be used?

    For example in you code , if i change way how slider movement is handled from
      this.label1 = new Ext.Net.Label
                {
                    ID = "Label1",
                    X = 215,
                    Y = 10
                };
    
    
                this.slider1.Listeners.ChangeComplete.Handler = "CompanyX.Update();";
    
                this.Add(this.slider1);
                this.Add(this.label1);
            }
    to

         this.label1 = new Ext.Net.Label
                {
                    ID = "Label1",
                    X = 215,
                    Y = 10
                };
    
    
                //this.slider1.Listeners.ChangeComplete.Handler = "CompanyX.Update();";
    
                this.Add(this.slider1);
                this.Add(this.label1);
    
                slider1.DirectEvents.Change.Event += this.HandleActivate;
            }
    
            public void HandleActivate(object sender, DirectEventArgs args)
            {
                int i = 1;
                i += 1;
    
            }
    It doesent work and i got error

    The control with ID 'Slider1' not found
    
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 
    
    Exception Details: System.Web.HttpException: The control with ID 'Slider1' not found
    
    Source Error: 
    
    
    Line 3195:                    if (ctrl == null)
    Line 3196:                    {
    Line 3197:                        throw new HttpException("The control with ID '{0}' not found".FormatWith(controlID));
    Line 3198:                    }
    Line 3199:                }
    
    Source File: c:\Ext.NET\ext.net.community.1.1.full.source\Ext.Net\Core\ResourceManager\ResourceManager.cs    Line: 3197 
    
    Stack Trace: 
    
    
    [HttpException (0x80004005): The control with ID 'Slider1' not found]
       Ext.Net.ResourceManager.RaisePostBackEvent(String eventArgument) in c:\Ext.NET\ext.net.community.1.1.full.source\Ext.Net\Core\ResourceManager\ResourceManager.cs:3197
       System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
       System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +175
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1565
    
    Version Information: Microsoft .NET Framework Version:2.0.50727.5446; ASP.NET Version:2.0.50727.5420
  7. #7
    Any dynamic control must be recreated on each request if you want to handle its server side events
  8. #8
    Hello Vladimir,

    Yes, i know this. Ofcourse you cannot expect to call something that is not exist ats is done here in example of geoffrey.mcgill
    but i just want to say, that this example is correct for small program, where each situation can be handled with
    directmethods , but completely unused for big projects.
    And there, for big projects situation can be handled with other way, that i give in another thread for dynamic creation.

Similar Threads

  1. [CLOSED] Slider control - SetValue()
    By DougMcDonald in forum 1.x Legacy Premium Help
    Replies: 10
    Last Post: Jul 16, 2012, 9:47 PM
  2. Replies: 3
    Last Post: Jan 04, 2012, 9:14 AM
  3. Replies: 11
    Last Post: Aug 11, 2011, 11:07 AM
  4. Bug with dynamic Add/Remove of panels
    By decho in forum 1.x Help
    Replies: 7
    Last Post: Aug 10, 2011, 10:16 AM
  5. Issues with dynamic IDs and tab panels
    By mindcore1 in forum 1.x Legacy Premium Help
    Replies: 1
    Last Post: Dec 21, 2008, 4:41 PM

Posting Permissions