multiple non-modal RadWindow - not removing from RadWindowManager

6 posts, 0 answers
  1. Gerhard
    Gerhard avatar
    3 posts
    Member since:
    Aug 2011

    Posted 23 Sep 2011 Link to this post

    I am still in a telerik evaluation phase and working with an evaluation copy.
    I am very new to web-application development, so forgive me if my question is dump.

    From a record-selection form I want to allow the user to call multiple update forms.
    This works without problems.
    But if I close one or all of the individual update forms and than call up additionally update-forms, all the previously created forms are popping up again. What have I forgotten?

    To demonstrate my problem see the following example.
    Just press the [New RadWindow] button multiple times.
    Then close all created windows by pressing [Close Window].
    When you then press the [New RadWindow] all the previously created forms and a new one are showing.
    How can I supress the showing of previusly closed forms?

    Default.aspx

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Default" %>
     
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     
    <head runat="server">
        <title></title>
        <telerik:RadStyleSheetManager id="RadStyleSheetManager1" runat="server" />
    </head>
    <body>
        <form id="form1" runat="server">
        <telerik:RadScriptManager ID="RadScriptManager1" runat="server">
            <Scripts>
                <%--Needed for JavaScript IntelliSense in VS2010--%>
                <%--For VS2008 replace RadScriptManager with ScriptManager--%>
                <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.Core.js" />
                <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQuery.js" />
                <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQueryInclude.js" />
            </Scripts>
        </telerik:RadScriptManager>
        <script type="text/javascript">
            //Put your JavaScript code here.
        </script>
        <telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
        </telerik:RadAjaxManager>
        <div>
     
            <telerik:RadWindowManager ID="RadWindowManager1" runat="server">
            </telerik:RadWindowManager>
     
        </div>
        <telerik:RadButton ID="RadButton1" runat="server" onclick="RadButton1_Click"
            Text="New RadWindow">
        </telerik:RadButton>
        <asp:RadioButtonList ID="RadioButtonList1" runat="server">
            <asp:ListItem>use Form.Controls.Add</asp:ListItem>
            <asp:ListItem Selected="True">use RadWindowManager.Add</asp:ListItem>
        </asp:RadioButtonList>
        </form>
    </body>
    </html>

    Default.aspx.cs
    using System;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
     
    using System.Data;
    using System.Configuration;
    using System.Web.Security;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using Telerik.Web.UI;
     
    public partial class Default : System.Web.UI.Page
    {
        public static int Counter = 0;
     
        protected void Page_Load(object sender, EventArgs e)
        {
     
        }
     
        protected void RadButton1_Click(object sender, EventArgs e)
        {
            RadWindow window1 = new RadWindow();
            window1.NavigateUrl = "WebForm2.aspx";
            window1.ID = string.Format("NonModalForm{0}", Counter++.ToString());
            window1.Title = window1.ID;
            window1.Behaviors = Telerik.Web.UI.WindowBehaviors.Close
                              | Telerik.Web.UI.WindowBehaviors.Resize
                              | Telerik.Web.UI.WindowBehaviors.Move;
            window1.Top = 80 + Counter * 20;
            window1.Left = Counter * 20;
            window1.Width = 200;
            window1.Height = 100;
            window1.Modal = false;
            window1.KeepInScreenBounds = true;// false; // seem to have no effect ( tested with IE );
            window1.VisibleStatusbar = false;
            window1.ShowContentDuringLoad = false;
            window1.EnableViewState = true;// false;
            window1.DestroyOnClose = false; // if true I get error in my real app.
            window1.VisibleOnPageLoad = true;
            switch (RadioButtonList1.SelectedValue)
            {
                case "use Form.Controls.Add"   : this.Form.Controls.Add(window1)       ; break; // this will show the window - but did not show multiple non-modal windows.
                case "use RadWindowManager.Add": RadWindowManager1.Windows.Add(window1); break; // RadWindowManager needed to show multiple non-modal windows - but Manager did not release windows.
            }
        }
    }

    WebForm2.aspx
    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="RadControlsWebApp_FormFLow.WebForm2" %>
     
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
         
            <telerik:RadScriptManager ID="RadScriptManager1" Runat="server">
            </telerik:RadScriptManager>
                <telerik:RadCodeBlock id="RadCodeBlock1" runat="server">
                    <script type="text/javascript">
     
                        function GetRadWindow() {
                            var oWindow = null;
                            if (window.radWindow) oWindow = window.radWindow;
                            else if (window.frameElement.radWindow) oWindow = window.frameElement.radWindow;
                            return oWindow;
                        }
     
                    </script>
                </telerik:RadCodeBlock>
     
            <telerik:RadButton ID="RadButton1" runat="server" Text="Close Form"
                onclick="RadButton1_Click">
            </telerik:RadButton>
         
        </div>
        </form>
    </body>
    </html>


    WebForm2.aspx.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
     
    using RadControlsWebApp_FormFLow;
     
    namespace RadControlsWebApp_FormFLow
    {
        public partial class WebForm2 : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
     
            }
     
            protected void RadButton1_Click(object sender, EventArgs e)
            {
                // close RadWindow
                ClientScript.RegisterStartupScript(GetType()
                    , "WindowCloseScript"
                    , "<script type='text/javascript'> var oWindow = GetRadWindow(); oWindow.Close(); </script>"
                    );
     
            }
        }
    }


  2. Marin Bratanov
    Admin
    Marin Bratanov avatar
    4627 posts

    Posted 23 Sep 2011 Link to this post

    Hi Gerhard,

    Please examine the following sticky forum thread on the matter of opening RadWindows from the server: http://www.telerik.com/community/forums/aspnet-ajax/window/opening-radwindow-from-the-server.aspx. The behavior you get is expected when you set the VisibleOnPageLoad property to true - each RadWindow you create is shown when the page loads after the postback. What you should do is explained in the above link - either injecting a script, or disabling the viewstate.


    Kind regards,
    Marin
    the Telerik team
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now
  3. Gerhard
    Gerhard avatar
    3 posts
    Member since:
    Aug 2011

    Posted 23 Sep 2011 Link to this post

    Thank you Marin for your quick answer.

    I followed the instructions you gave me, but without success.
    Either I get no window at all or only one window .
    I had tested the option 1 to 3 and all together. Nothing did it right.

    In my simple mind, I thought that the real problem is that I do a

    • RadWindowManager1.Windows.Add(RadWindow1)

    but never a

    • RadWindowManager1.Windows.Remove.

    There does exist a Remove. But where and how should I call it. Or I am totally wrong?

    Regards
    Gerhard


    A typical page would look like:
  4. Marin Bratanov
    Admin
    Marin Bratanov avatar
    4627 posts

    Posted 26 Sep 2011 Link to this post

    Hello Gerhard,

    What I strongly advise as a best approach is to use only JavaScript and not to perform postback in order to open RadWindows.

    Generally the RadWindowManager is not designed to modify the collection of windows on the server, especially because it needs to be disposed and recreated after each postback. You can try storing the index of a desired RadWindow or a reference to it then removing it via this index or reference, for example:
    string identifier = string.Format("NonModalForm{0}", Counter.ToString());
    Session[identifier] = RadWindowManager1.Windows.IndexOf(window1).ToString();
    when you add the RadWindow and this will remove it:
    string identifier = string.Format("NonModalForm{0}", Counter.ToString());
    Session[identifier] = RadWindowManager1.Windows.IndexOf(window1).ToString();

    But this approach will not work after a second postback, for example, as the collection will be recreated and the one that we just deleted will no longer exist, thus the previously correct references will now be incorrect as a collection does not allow empty "cells".

    All that being said - I advise against modifying this collection, as it exists mainly to allow RadWindows to preserve their viewstate and to allow the manager to access them by their IDs in order for radopen to work.

    Please note option 2) in the linked post - setting the VisibleOnPageLoad property to false when needed. I believe this approach is the second easiest after moving the code entirely to the client-side, for example:
    string identifier = string.Format("NonModalForm{0}", TextBox1.Text);
    foreach (RadWindow item in RadWindowManager1.Windows)
    {
        if (item.Title == identifier)
        {
            item.VisibleOnPageLoad = false;
        }
    }
    You can see the result from this in the following video: http://screencast.com/t/HCb7hcd7pD. How you can integrate this with the close button - in the OnClientClose event you can store the RadWindow's title in a hidden field, in the code behind you can obtain this ttile to identify the RadWindow and reset its VisibleOnPageLoad property. In order to avoid a full postback you can use AJAX and only update the RadWindowManager. For your convenience I am attaching a page that does this. I hope it helps you achieve the desired functionality.


    Best wishes,
    Marin
    the Telerik team

    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now
  5. Gerhard
    Gerhard avatar
    3 posts
    Member since:
    Aug 2011

    Posted 27 Sep 2011 Link to this post

    Hello Marin,
     
    thank you for your nice example. It brought me a big step further.

    I made little adjustments (see attached files) and it works as expected with one exception:
    When the window is not created the normal way (Windows.Add) but either re-use a hidden window or by reactivating a duplicate window, this window is not the active one. It seems that by default always the window with the highest index is activated. 

    My question: How can I activate a specific window?

    Hope you can help me the last time.

    Regards
    Gerhard

    Default.aspx

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Default" %>
     
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     
    <head runat="server">
        <title></title>
        <telerik:RadStyleSheetManager id="RadStyleSheetManager1" runat="server" />
    </head>
    <body>
        <form id="form1" runat="server">
        <telerik:RadScriptManager ID="RadScriptManager1" runat="server">
        </telerik:RadScriptManager>
        <script type="text/javascript">
            //Put your JavaScript code here.
        </script>
        <telerik:RadAjaxManager ID="RadAjaxManager1" runat="server" OnAjaxRequest="AjaxRequestHideWindow">
            <AjaxSettings>
                <telerik:AjaxSetting AjaxControlID="RadAjaxManager1">
                    <UpdatedControls>
                        <telerik:AjaxUpdatedControl ControlID="RadWindowManager1" />
                    </UpdatedControls>
                </telerik:AjaxSetting>
            </AjaxSettings>
        </telerik:RadAjaxManager>
        <div>
     
            <telerik:RadWindowManager ID="RadWindowManager1" runat="server" OnClientClose="saveIdentifier">
            </telerik:RadWindowManager>
     
            <telerik:RadWindow ID="RadWindow1" runat="server" Height="16px" Width="162px">
            </telerik:RadWindow>
     
        </div>
        <telerik:RadButton ID="RadButton1" runat="server" onclick="RadButton1_Click"
            Text="New RadWindow">
        </telerik:RadButton>
        <asp:HiddenField runat="server" ID="IdentifierField" />
        <telerik:RadCodeBlock runat="server" ID="RadCodeBlock2">
        <script type="text/javascript">
            function saveIdentifier(sender, args) {
                $get("<%=IdentifierField.ClientID %>").value = sender.GetUrl();
                $find("<%=RadAjaxManager1.ClientID %>").ajaxRequest();
            }
        </script>
        </telerik:RadCodeBlock>
        </form>
    </body>
    </html>

    Default.aspx.cs

    using System;
    using Telerik.Web.UI;
     
     
    public partial class Default : System.Web.UI.Page
    {
        public static int Counter = 0;
     
        private void SetWindowValues(RadWindow rw, string urlAndIdentifier)
        {
            rw.ID = string.Format("NonModalForm{0}", Counter.ToString());
            rw.NavigateUrl = urlAndIdentifier;
            rw.Title = urlAndIdentifier;
            rw.Behaviors = Telerik.Web.UI.WindowBehaviors.Close
                         | Telerik.Web.UI.WindowBehaviors.Resize
                         | Telerik.Web.UI.WindowBehaviors.Move;
            rw.Top = Counter * 100;
            rw.Left = Counter * 20;
            rw.Width = 400;
            rw.Height = 80;
            rw.Modal = false;
            rw.KeepInScreenBounds = true;// false; // seem to have no effect ( tested with IE );
            rw.VisibleStatusbar = false;
            rw.ShowContentDuringLoad = false;
            rw.EnableViewState = true;// false;
            rw.DestroyOnClose = false; // if true I get error in my real app.
            rw.VisibleOnPageLoad = true; //" set to false when window is closed - see AjaxRequestHideWindow
        }
     
        private bool ReactivateWindowIfAlreadyVisible(string urlAndIdentifier)
        {
            foreach (RadWindow rw in RadWindowManager1.Windows)
            {
                if ((rw.NavigateUrl == urlAndIdentifier)
                     && (rw.VisibleOnPageLoad))
                {
                    // if there exists an active window with same identifier that window should get the Activate one
                    RadWindowManager1.RadAlert("Window " + '"' + urlAndIdentifier + '"' + " already shown", 330, 100, "already shown", "");
                    // how to make the RadWindow the Active one?
                    return true;
                }
            }
            return false;
        }
        private bool ReUseUnvisibleWindowIfAny(string urlAndIdentifier)
        {
            foreach (RadWindow rw in RadWindowManager1.Windows)
            {
                if (!rw.VisibleOnPageLoad)
                {
                    // if there exists an unvisible window - re-use it
                    SetWindowValues(rw, urlAndIdentifier);
                    // how to make the RadWindow the Active one?
                    return true;
                }
            }
            return false;
        }
        protected void RadButton1_Click(object sender, EventArgs e)
        {
            string urlAndIdentifier = string.Format("WebForm2.aspx?MyWinID={0}", Counter++.ToString());
     
            if (!ReactivateWindowIfAlreadyVisible(urlAndIdentifier))
            {
                if (!ReUseUnvisibleWindowIfAny(urlAndIdentifier))
                {
                    RadWindow rw = new RadWindow();
                    SetWindowValues(rw, urlAndIdentifier);
                    RadWindowManager1.Windows.Add(rw);
                }
            }
        }
     
        protected void AjaxRequestHideWindow(object sender, AjaxRequestEventArgs e)
        {
            foreach ( RadWindow rw in RadWindowManager1.Windows)
            {
                if (    (rw.NavigateUrl == IdentifierField.Value)
                     && (rw.VisibleOnPageLoad) )
                {
                    rw.VisibleOnPageLoad = false;
                    break;
                }
            }
        }
    }

    WebForm2.aspx

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="RadControlsWebApp_FormFLow.WebForm2" %>
     
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form2" runat="server">
        <div>
         
            <telerik:RadScriptManager ID="RadScriptManager1" Runat="server">
            </telerik:RadScriptManager>
                <telerik:RadCodeBlock id="RadCodeBlock1" runat="server">
                    <script type="text/javascript">
     
                        function GetRadWindow() {
                            var oWindow = null;
                            if (window.radWindow) oWindow = window.radWindow;
                            else if (window.frameElement.radWindow) oWindow = window.frameElement.radWindow;
                            return oWindow;
                        }
     
                    </script>
                </telerik:RadCodeBlock>
     
            <telerik:RadButton ID="RadButton1" runat="server" Text="Close Form"
                onclick="RadButton1_Click">
            </telerik:RadButton>
         
        </div>
        </form>
    </body>
    </html>

    WebForm2.aspx.cs

    using System;
    using Telerik.Web.UI;
     
    namespace RadControlsWebApp_FormFLow
    {
        public partial class WebForm2 : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
     
            }
     
            protected void RadButton1_Click(object sender, EventArgs e)
            {
                // close RadWindow
                ClientScript.RegisterStartupScript(GetType()
                    , "WindowCloseScript"
                    , "<script type='text/javascript'> var oWindow = GetRadWindow(); oWindow.Close(); </script>"
                    );
            }
        }
    }


  6. Marin Bratanov
    Admin
    Marin Bratanov avatar
    4627 posts

    Posted 29 Sep 2011 Link to this post

    Hi Gerhard,

    The RadWindow's Client-side API offers the setActive() method when you wish to programmatically activate a certain RadWindow. You can inject it from the code-behind as described in this help article. A simple example follows:
    protected void activete_certain_RadWindow(RadWindow rw) 
    {
        ScriptManager.RegisterStartupScript(this, this.GetType(), "key1", "function f(){setTimeout(function(){$find('" + rw.ClientID + "').setActive(true);},0);Sys.Application.remove_load(f);}Sys.Application.add_load(f);", true);
    }

    This function takes as an argument the RadWindow you have pinpointed in your custom logic as the one that should be activated (I would advise that you revise it, as constantly increasing the counter will result in your conditions not being met at all).

    Note the utilization of the Sys.Application.Load event and the timeout. Please keep in mind that after each postback the RadWIndowManager's Windows collection is recreted and thus the IDs of these dynamically created instances will not be persisted (as is the case with any other dynamic collection).


    On a side note - may I suggest an alternative approach - place the buttons that execute the code-behind logic in update panels so that they don't dispose the entire page and therefore the RadWindows can be manipulated as intended - on the client. In order to show a RadWindow you can inject a call to radopen(<your url>, <window name>). Where you can even omit the name parameter and pass null, which will result in a new RadWindow being created on the client. More information on this is available here. This way the last opened RadWindow will be active, the IDs you provide will be persisted and thus you will be able to $find() them more easily and activate a different one if needed (you could also reference them via the RadWindowManager's Client-side API). This will also prevent full page postbacks, effectively improving the user experience.

    Kind regards,
    Marin
    the Telerik team
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now
Back to Top