[CLOSED] DirectMethod missing when control created dynamically

  1. #1

    [CLOSED] DirectMethod missing when control created dynamically

    Guys,

    This might be a little complicated to explain, and I'll try to give all the relevant code samples. OK, here goes:

    Setup:
    From a few places in my application, I want to be able to create/edit some data using a window. So, instead of replicating the same window in markup in 2 places, I thought it would be good code design/reuse to use the same strategy as the 'SimpleTasks' example on examples.ext.net. I got everything working first in markup, and have been spending the last several days trying to get everything working again after creating it dynamically.

    In a nutshell, the problem I'm having is:
    On my window, I have a button that fires a client side 'save' function. This in turn, collects the values of the form fields and submits them to a 'Save' direct method. When I create the Window in code, even when registering the control as a directmethod control (as in the example), my DirectMethod is not showing up in the client side DOM.

    Here goes with as simplified an example as I can:

    First, grid on ASPX page:
            <ext:GridPanel ID="gpPasswords" runat="server" StoreID="stPasswords" TrackMouseOver="true"
                StripeRows="true" Header="false" Border="false"
                Collapsible="true" AnimCollapse="true" AutoHeight="true">
                <ColumnModel>
                    <Columns>
                        <ext:ImageCommandColumn>
                            <Commands>
                                <ext:ImageCommand CommandName="EditPassword" Text="Edit" Icon="TableEdit">
                                    <ToolTip Text="Edit Password" />
                                </ext:ImageCommand>
                            </Commands>
                        </ext:ImageCommandColumn>
                        <ext:Column ColumnID="PasswordType" Header="Type" Sortable="true" DataIndex="PasswordType" />
                        <ext:Column ColumnID="Resource" Header="Resource" Sortable="true" DataIndex="Resource" />
                        <ext:Column ColumnID="Location" Header="Location/Url" Sortable="true" DataIndex="Location" />
                        <ext:Column ColumnID="Username" Header="Username" Sortable="true" DataIndex="Resource" />
                        <ext:Column ColumnID="Password" Header="Password" Sortable="false" DataIndex="Password">
                            <Renderer Fn="pwdRenderer" />
                            <Commands>
                                <ext:ImageCommand Icon="Magnifier" ToolTip-Text="Show Password" CommandName="ShowPassword"></ext:ImageCommand>
                                <ext:ImageCommand Icon="PastePlain" ToolTip-Text="Copy to Clipboard" CommandName="CopyToClipboard"></ext:ImageCommand>
                            </Commands>
                        </ext:Column>
                        <ext:DateColumn ColumnID="ActiveDate" Header="Active From" Sortable="true" DataIndex="ActiveDate"
                            Format="d">
                        </ext:DateColumn>
                        <ext:DateColumn ColumnID="ExpirationDate" Header="Expires" Sortable="true" DataIndex="ExpirationDate"
                            Format="d">
                        </ext:DateColumn>
                        <ext:DateColumn ColumnID="ModifiedDate" Header="Last Modified" Sortable="true" DataIndex="ModifiedDate"
                            Format="n/j/Y g:i a" />
                        <ext:Column ColumnID="ModifiedBy" Header="Modified By" Sortable="true" DataIndex="ModifiedBy"></ext:Column>
                    </Columns>
                </ColumnModel>
                <SelectionModel>
                    <ext:RowSelectionModel ID="SelectedRowModel1" runat="server" SingleSelect="true" />
                </SelectionModel>
                <Listeners>
                    <Command Handler="gpPasswords_Command(command, record);" />
                </Listeners>
                <View>
                    <ext:GridView ID="GridView1" runat="server" ForceFit="true" />
                </View>
                <Plugins>
                    <ext:RowExpander ID="RowExpander1" runat="server">
                        <Template ID="NoteTemplate" runat="server">
                            <Html>
                                <table border="0" cellpadding="10" cellspacing="0" width="100%">
                                    <tr>
                                        <td style="font-weight:bold; width:50px; padding-top: 5px; padding-bottom: 5px; padding-left: 10px;">Notes:</td>
                                        <td style="text-align:left; width:90%; padding-top: 5px; padding-bottom:5px;">
                                            {Notes}
                                        </td>
                                    </tr>
                                </table>
                            </Html>
                        </Template>
                    </ext:RowExpander>
                    <ext:GridFilters runat="server" ID="GridFilters1" Local="true">
                        <Filters>
                            <ext:StringFilter DataIndex="PasswordType" />
                            <ext:StringFilter DataIndex="Resource" />
                            <ext:StringFilter DataIndex="Location" />
                            <ext:StringFilter DataIndex="Username" />
                            <ext:DateFilter DataIndex="ActiveDate">
                                <DatePickerOptions runat="server" TodayText="Now" />
                            </ext:DateFilter>
                            <ext:DateFilter DataIndex="ExpirationDate">
                                <DatePickerOptions runat="server" TodayText="Now" />
                            </ext:DateFilter>
                            <ext:DateFilter DataIndex="ModifiedDate">
                                <DatePickerOptions runat="server" TodayText="Now" />
                            </ext:DateFilter>
                            <ext:StringFilter DataIndex="ModifiedBy" />
                        </Filters>
                    </ext:GridFilters>
                </Plugins>
            </ext:GridPanel>
    The pertinent parts are that I have an Edit ImageCommand column and it gets handled by gpPasswords_command (client side on the same page):
        <script language="javascript" type="text/javascript">
        var gpPasswords_Command = function (command, record) {
            switch (command) {
                case "EditPassword":
                    Ext.net.DirectMethods.EditPassword(record.data.PasswordId);                
                    break;
        }
        </script>
    The Edit Password DirectMethod is on the same ASPX page (in codebehind):
            [DirectMethod]
            public void EditPassword(int PasswordId)
            {
                new LogicSpeak.Harmony.Portal.UC.Ext.PasswordWindow(PasswordId).Render(this.Page.Form.ClientID, RenderMode.RenderTo);
            }
    My PasswordWindow is an Ext.net Window with additional "stuff":
    #region Using
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using Ext.Net;
    using Ext.Net.Utilities;
    using LogicSpeak.Extensions;
    using System.Web.UI.WebControls;
    using LogicSpeak.Harmony.Components;
    using LogicSpeak.Harmony.BLL;
    using LogicSpeak.Configuration;
    using LogicSpeak.Data.Sql;
    #endregion
     
    namespace LogicSpeak.Harmony.Portal.UC.Ext
    {
        [DirectMethodProxyID(IDMode = DirectMethodProxyIDMode.None)]
        public class PasswordWindow : Window
        {
            #region Instance
            private const string SCOPE = "LogicSpeak.PasswordWindow";
            TList<Lookup> PasswordTypes;
            private Password PasswordInfo;
            private int PasswordId;
            private global::Ext.Net.Store stPasswordTypes;
            private global::Ext.Net.FormPanel passwordForm;
            private global::Ext.Net.Container outerContainer;
            private global::Ext.Net.Container leftColumn;
            private global::Ext.Net.Container rightColumn;
            private global::Ext.Net.Container bottomRow;
            private PasswordFolderField ddlFolder;
            private global::Ext.Net.TextField txtResource;
            private global::Ext.Net.TextField txtLocation;
            private global::Ext.Net.ComboBox ddlPasswordType;
            private global::Ext.Net.TextField txtUsername;
            private global::Ext.Net.TriggerField txtPassword;
            private global::Ext.Net.DateField dfActive;
            private global::Ext.Net.DateField dfExpiration;
            private global::Ext.Net.TextArea txtNotes;
            private global::Ext.Net.Button btnPasswordSave;
            private global::Ext.Net.Button btnPasswordCancel;
            private global::Ext.Net.KeyBinding kbPasswordSave;
            private global::Ext.Net.KeyBinding kbPasswordCancel;
            #endregion
            
            public PasswordWindow()
            {
                this.PasswordId = 0;
                LoadData();
                InitControls();
                LoadDefaultForm();
            }
            public PasswordWindow(int PasswordId)
            {
                this.PasswordId = PasswordId;
                LoadData();
                InitControls();
                LoadForm();
            }
            #region Methods
            private void LoadData()
            {	//Unrelated database access code
            }
            private void LoadDefaultForm()
            {
                ddlFolder.UnderlyingValue = string.Empty;
                ddlFolder.Text = string.Empty;
                ddlPasswordType.ClearValue();
                txtResource.Text = string.Empty;
                txtLocation.Text = string.Empty;
                txtUsername.Text = string.Empty;
                txtPassword.Text = string.Empty;
                txtNotes.Text = string.Empty;
                dfActive.Clear();
                dfExpiration.Clear();
            }
            private void LoadForm()
            {
                LogicSpeak.Security.Encryption decrypter = new Security.Encryption();
                ddlFolder.UnderlyingValue = PasswordInfo.PasswordFolderId.ToString();
                ddlFolder.Text = PasswordInfo.PasswordFolderIdSource.Name;
                ddlPasswordType.SelectByValue(PasswordInfo.PasswordTypeId.ToString());
                txtResource.Text = PasswordInfo.Resource;
                txtLocation.Text = PasswordInfo.Location;
                txtUsername.Text = PasswordInfo.Username;
                txtPassword.Text = decrypter.Decrypting(PasswordInfo.Password, ConfigurationManagerHelper.GetAppSetting("PasswordSalt"));
                txtNotes.Text = PasswordInfo.Notes;
                if (PasswordInfo.ActiveDate.IsNot(SqlHelper.MinDateTime))
                {
                    dfActive.SelectedDate = PasswordInfo.ActiveDate;
                }
                if (PasswordInfo.ExpirationDate.IsNot(SqlHelper.MinDateTime))
                {
                    dfExpiration.SelectedDate = PasswordInfo.ExpirationDate;
                }
            }
            private void InitIcons()
            {
                this.ResourceManager.RegisterIcon(global::Ext.Net.Icon.KeyAdd);
                this.ResourceManager.RegisterIcon(global::Ext.Net.Icon.Key);
                this.ResourceManager.RegisterIcon(global::Ext.Net.Icon.Disk);
            }
            private void InitControls()
            {
                #region this(window) & Outer Container
                this.ID = string.Format("PasswordWindow_{0}", PasswordId);
                this.AutoHeight = true;
                this.ButtonAlign = Alignment.Right;
                this.CloseAction = global::Ext.Net.CloseAction.Close;
                this.Collapsible = false;
                this.Icon = PasswordId.Is(0) ? global::Ext.Net.Icon.KeyAdd : global::Ext.Net.Icon.Key;
                this.InitCenter = true;
                this.Layout = "AutoLayout";
                this.Modal = true;
                this.PaddingSummary = "5px 5px 0";
                this.Resizable = false;
                this.Title = PasswordId.Is(0) ? "Enter New Password" : "Edit Password";
                this.Width = new Unit(450, UnitType.Pixel);
                this.InitIcons();
                this.CustomConfig.Add(new ConfigItem("passwordId", PasswordId.ToString(), ParameterMode.Raw));
     
                passwordForm = new FormPanel()
                {
                    BaseCls = "x-plain",
                    Ref = "passwordForm",
                    RenderFormElement = false,
                    CustomConfig =
                    {
                        new ConfigItem("margins", "10 10 5 10", ParameterMode.Value)
                    }
                };
     
                outerContainer = new Container();
                outerContainer.Layout = "Column";
                outerContainer.Height = new Unit(200, UnitType.Pixel);
                #endregion
     
                #region Left Column
                leftColumn = new Container();
                leftColumn.LabelAlign = global::Ext.Net.LabelAlign.Top;
                leftColumn.Layout = "Form";
                leftColumn.ColumnWidth = .5;
     
                ddlFolder = new PasswordFolderField();
                ddlFolder.ID = "ddlFolder";
                ddlFolder.AnchorHorizontal = "95%";
                ddlFolder.DataIndex = "PasswordFolderId";
                ddlFolder.TabIndex = 1;
                leftColumn.Items.Add(ddlFolder);
     
                stPasswordTypes = new Store();
                stPasswordTypes.ID = "stPasswordTypes";
                stPasswordTypes.AutoLoad = false;
                JsonReader reader = new JsonReader();
                reader.Fields.Add(new RecordField("LookupId"));
                reader.Fields.Add(new RecordField("Description"));
                stPasswordTypes.Reader.Add(reader);
                stPasswordTypes.DataSource = PasswordTypes;
                stPasswordTypes.DataBind();
     
                ddlPasswordType = new ComboBox();
                ddlPasswordType.ID = "ddlPasswordType";
                ddlPasswordType.FieldLabel = "Password Type";
                ddlPasswordType.ValueField = "LookupId";
                ddlPasswordType.DisplayField = "Description";
                ddlPasswordType.ForceSelection = true;
                ddlPasswordType.SelectOnFocus = true;
                ddlPasswordType.LazyInit = false;
                ddlPasswordType.Mode = DataLoadMode.Default;
                ddlPasswordType.TriggerAction = TriggerAction.All;
                ddlPasswordType.TypeAhead = true;
                ddlPasswordType.ValidateOnBlur = true;
                ddlPasswordType.BlankText = "Type is required.";
                ddlPasswordType.AllowBlank = false;
                ddlPasswordType.DataIndex = "PasswordTypeId";
                ddlPasswordType.Store.Add(stPasswordTypes);
                ddlPasswordType.TabIndex = 2;
                leftColumn.Items.Add(ddlPasswordType);
     
                txtLocation = new TextField();
                txtLocation.ID = "txtLocation";
                txtLocation.FieldLabel = "Location/Link";
                txtLocation.AnchorHorizontal = "95%";
                txtLocation.DataIndex = "Location";
                txtLocation.TabIndex = 3;
                leftColumn.Items.Add(txtLocation);
     
                dfActive = new DateField();
                dfActive.ID = "dfActive";
                dfActive.DataIndex = "Active";
                dfActive.FieldLabel = "Active Date";
                dfActive.AnchorHorizontal = "95%";
                dfActive.TabIndex = 7;
                leftColumn.Items.Add(dfActive);
     
                outerContainer.Items.Add(leftColumn);
                #endregion
     
                #region Right Column
                rightColumn = new Container();
                rightColumn.LabelAlign = global::Ext.Net.LabelAlign.Top;
                rightColumn.Layout = "Form";
                rightColumn.ColumnWidth = .5;
     
                txtResource = new TextField();
                txtResource.ID = "txtResource";
                txtResource.FieldLabel = "Resource";
                txtResource.AnchorHorizontal = "95%";
                txtResource.DataIndex = "Resource";
                txtResource.TabIndex = 4;
                rightColumn.Items.Add(txtResource);
     
                txtUsername = new TextField();
                txtUsername.ID = "txtUsername";
                txtUsername.FieldLabel = "Username";
                txtUsername.AnchorHorizontal = "95%";
                txtUsername.DataIndex = "Username";
                txtUsername.TabIndex = 5;
                rightColumn.Items.Add(txtUsername);
     
                txtPassword = new TriggerField();
                txtPassword.ID = "txtPassword";
                txtPassword.FieldLabel = "Password";
                txtPassword.InputType = InputType.Password;
                txtPassword.AnchorHorizontal = "95%";
                txtPassword.TabIndex = 6;
                txtPassword.DataIndex = "Password";
     
                FieldTrigger ftShowPassword = new FieldTrigger();
                ftShowPassword.Icon = TriggerIcon.SimpleMagnify;
                ftShowPassword.Qtip = "Show password";
                txtPassword.Triggers.Add(ftShowPassword);
     
                FieldTrigger ftCopyToClipboard = new FieldTrigger();
                ftCopyToClipboard.Icon = TriggerIcon.SimpleGet;
                ftCopyToClipboard.Qtip = "Copy to clipboard";
                txtPassword.Triggers.Add(ftCopyToClipboard);
     
                rightColumn.Items.Add(txtPassword);
     
                dfExpiration = new DateField();
                dfExpiration.ID = "dfExpiration";
                dfExpiration.DataIndex = "Expiration";
                dfExpiration.FieldLabel = "Expiration Date";
                dfExpiration.AnchorHorizontal = "95%";
                dfExpiration.TabIndex = 8;
                rightColumn.Items.Add(dfExpiration);
     
                outerContainer.Items.Add(rightColumn);
                #endregion
     
                passwordForm.Items.Add(outerContainer);
     
                #region Bottom Row
                bottomRow = new Container();
                bottomRow.LabelAlign = global::Ext.Net.LabelAlign.Top;
                bottomRow.Layout = "Form";
     
                txtNotes = new TextArea();
                txtNotes.ID = "txtNotes";
                txtNotes.Height = new Unit(125, UnitType.Pixel);
                txtNotes.FieldLabel = "Notes";
                txtNotes.AnchorHorizontal = "100%";
                txtNotes.DataIndex = "Notes";
                txtNotes.TabIndex = 9;
                bottomRow.Items.Add(txtNotes);
     
                passwordForm.Items.Add(bottomRow);
                #endregion
     
                #region Actions
                btnPasswordSave = new global::Ext.Net.Button();
                btnPasswordSave.ID = "btnPasswordSave";
                btnPasswordSave.Icon = global::Ext.Net.Icon.Disk;
                btnPasswordSave.Text = "Save";
                btnPasswordSave.TabIndex = 10;
                this.Buttons.Add(btnPasswordSave);
     
                btnPasswordCancel = new global::Ext.Net.Button();
                btnPasswordCancel.ID = "btnPasswordCancel";
                btnPasswordCancel.Text = "Cancel";
                btnPasswordCancel.TabIndex = 11;
                this.Buttons.Add(btnPasswordCancel);
     
                this.Items.Add(passwordForm);
     
                kbPasswordSave = new KeyBinding();
                kbPasswordSave.Alt = true;
                kbPasswordSave.Keys.Add(new Key() {Code = KeyCode.S});
                this.KeyMap.Add(kbPasswordSave);
     
                kbPasswordCancel = new KeyBinding(); 
                kbPasswordCancel.Alt = true;
                kbPasswordCancel.Keys.Add(new Key() { Code = KeyCode.C });
                this.KeyMap.Add(kbPasswordCancel);
                #endregion
            }
            #endregion
     
            #region Event Handlers
            protected override void OnLoad(EventArgs e)
            {
                base.OnLoad(e);
                this.ResourceManager.AddDirectMethodControl(this);
            }
            protected override void OnPreRender(EventArgs e)
            {
                base.OnPreRender(e);
     
                this.DefaultButton = btnPasswordSave.ClientID;
                btnPasswordSave.Handler = new JFunction(string.Concat(SCOPE, ".savePassword(", this.ClientID, ");")).ToScript();
                kbPasswordSave.Listeners.Event.Handler = new JFunction(string.Concat(SCOPE, ".savePassword(", this.ClientID, ");")).ToScript();
                btnPasswordCancel.Handler = new JFunction(this.ID + ".close();").ToScript();
                kbPasswordCancel.Listeners.Event.Handler = new JFunction(this.ID + ".close();").ToScript();
                txtPassword.Listeners.TriggerClick.Fn = string.Concat(SCOPE, ".passwordTrigger");
            }
            [DirectMethod]
            public void ShowPassword(bool ShowPassword)
            {
                try
                {
                    txtPassword.InputType = ShowPassword ? InputType.Text : InputType.Password;
                    rightColumn.Render(txtPassword, RenderMode.RenderTo);
                    global::Ext.Net.ResourceManager.AjaxSuccess = true;
                }
                catch (Exception ex)
                {
                    global::Ext.Net.ResourceManager.AjaxSuccess = false;
                    global::Ext.Net.ResourceManager.AjaxErrorMessage = ex.Message;
                }
            }
            [DirectMethod]
            public void SavePassword(int PasswordId, JsonObject values)
            {
                string Resource = string.Empty;
                string Location = string.Empty;
                string Username = string.Empty;
                string Password = string.Empty;
                DateTime ActiveDate = SqlHelper.MinDateTime;
                DateTime ExpirationDate = SqlHelper.MinDateTime;
                string Notes = string.Empty;
                int PasswordTypeId = 0;
                int PasswordFolderId = 0;
     
                try
                {
                    foreach (KeyValuePair<string, object> item in values)
                    {
                        if (item.Key.Contains("txtResource")) Resource = item.Value.ToString();
                        else if (item.Key.Contains("txtLocation")) Location = item.Value.ToString();
                        else if (item.Key.Contains("txtUsername")) Username = item.Value.ToString();
                        else if (item.Key.Contains("txtPassword")) Password = item.Value.ToString();
                        else if (item.Key.Contains("txtNotes")) Notes = item.Value.ToString();
                        else if (item.Key.Contains("ddlFolder")) PasswordFolderId = item.Value.ChangeType<int>();
                        else if (item.Key.Contains("ddlPasswordType")) PasswordTypeId = item.Value.ChangeType<int>();
                        else if (item.Key.Contains("dfActive")) ActiveDate = item.Value.ChangeType<DateTime>();
                        else if (item.Key.Contains("dfExpiration")) ExpirationDate = item.Value.ChangeType<DateTime>();
                    }
                    if (PasswordId.Is(0))
                    {
                        PasswordService.Instance.CreatePassword(
                            PasswordFolderId,
                            Resource,
                            Location,
                            PasswordTypeId,
                            Username,
                            Password,
                            Notes,
                            ActiveDate,
                            ExpirationDate,
                            EmployeeInfo.EmployeeId,
                            EmployeeInfo.Email1);
                    }
                    else
                    {
                        PasswordService.Instance.UpdatePassword(
                            PasswordId,
                            PasswordFolderId,
                            Resource,
                            Location,
                            PasswordTypeId,
                            Username,
                            Password,
                            Notes,
                            ActiveDate,
                            ExpirationDate,
                            EmployeeInfo.EmployeeId,
                            EmployeeInfo.Email1);
                    }
     
                    global::Ext.Net.ResourceManager.AjaxSuccess = true;
                }
                catch (Exception ex)
                {
                    global::Ext.Net.ResourceManager.AjaxSuccess = false;
                    global::Ext.Net.ResourceManager.AjaxErrorMessage = ex.Message;
                }
            }
            #endregion
        }
    }
    This control loads fine (except that the dropdown for PasswordType can't be set...for some reason when the SetByValue method is called, there are no entries in the collection, even though I had just loaded them up). The problem comes when clicking save. It calls a client side savePassword method in a "PasswordWindow.js" file:
    Ext.ns("LogicSpeak");
     
    LogicSpeak.PasswordWindow = {
        copyToClipboard: function (ft) {
            if (window.clipboardData && window.clipboardData.setData) {
                window.clipboardData.setData("Text", ft.getValue());
            }
            else {
                Ext.Msg.alert("Not Supported", "Sorry, your browser currently does not support copy to clipboard functionality.");
            }
        },
        savePassword: function (w) {
            if (!w.passwordForm.isValid()) {
                return;
            }
     
            var values = Ext.encode(w.passwordForm.getForm().getFieldValues());
            Ext.Msg.wait("Saving password...", "Progress");
     
            Ext.net.DirectMethods.SavePassword(w.passwordId, values, {
                success: function () {
                    Ext.Msg.hide();
                    w.close();
                    //Rebind grid?!?
                },
                failure: function (error, response) {
                    Ext.Msg.alert("Error saving password", response.responseText);
                }
            });
        },
        showPassword: function (ft) {
            if (ft.inputType == "password") {
                Ext.net.DirectMethods.ShowPassword(true, {
                    success: function (response) {
                    },
                    failure: function (error, response) {
                        Ext.Msg.alert("Error showing password", response.responseText);
                    }
                });
            }
            else {
                Ext.net.DirectMethods.ShowPassword(false, {
                    success: function () { },
                    failure: function (error, response) {
                        Ext.Msg.alert("Error hiding password", response.responseText);
                    }
                });
            }
        },
        passwordTrigger: function (el, trigger, index) {
            switch (index) {
                case 0:
                    LogicSpeak.PasswordWindow.showPassword(el);
                    break;
                case 1:
                    LogicSpeak.PasswordWindow.copyToClipboard(el);
                    break;
            }
        }
    };
    Finally...here's the problem. The savePassword attempts to call the Ext.net.DirectMethods.SavePassword (which is on the PasswordWindow) but it is undefined. I have been beating my head against a wall for 2 days trying to figure out why, given that I've followed the examples code as closely as I could, but I am thus far unsuccessful. Any ideas? Do I have some fundamentally wrong logic or properties set that are causing this to not work?

    Thanks so much in advance for your help.
    Jason
    Last edited by geoffrey.mcgill; Oct 07, 2010 at 7:45 PM. Reason: [CLOSED]
  2. #2
    Hi,

    1. DirectMethods are not supported for dynamic controls because we register direct methods during initial page load only (during direct event it is not supported)

    2. You don't recreate dynamic control on each request therefore even if we registered direct methods during direct event then ResourceManager could not find dynamic control

    I can suggest to use direct events and recreate dynamic control on each control (witout rendering, render it first time only)
  3. #3
    Vlad,
    Thanks for the quick response!
    • My apologies, but I'm having trouble understanding what you're suggesting as a workaround. Can you give me a quick explanation of how that would work? Possibly a pseudocode example?
    • Also, does this same thing apply for why on the dynamic control, the "RegisterClientScriptInclude" method doesn't work to register a .js file when the dynamic control is created?
    Thanks again...at least I understand why now. I really am trying to use good Ext.net recommended practices when building my application.
    Jason

    Quote Originally Posted by vladimir View Post
    Hi,

    1. DirectMethods are not supported for dynamic controls because we register direct methods during initial page load only (during direct event it is not supported)

    2. You don't recreate dynamic control on each request therefore even if we registered direct methods during direct event then ResourceManager could not find dynamic control

    I can suggest to use direct events and recreate dynamic control on each control (witout rendering, render it first time only)
  4. #4
    Hi,

    I prepared small sample which demonstrates dynamic windows with direct events and automatic recreation
    <%@ Page Language="C#"  %>
    <%@ 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">
        <title></title>
        
        <script runat="server">
            public class MyWindow : Window
            {
                private TextField field;
    
                // makes it via public fields for simplicity
                public delegate void DestroyOnClient(XControl ctrl);
                public event DestroyOnClient CloseEvent;
                
                protected override void OnInit(EventArgs e)
                {
                    base.OnInit(e);
                    this.SuspendScripting();
                    this.CloseAction = CloseAction.Close;
                    this.Title = DateTime.Now.ToLongTimeString();
                    this.Width = 300;
                    this.Height = 200;
                    this.Layout = "form";
                    this.field = new TextField { 
                        ID = this.ID + "_TextField",
                        FieldLabel = "FieldLabel"
                    };                
                    this.Items.Add(field);
                    
                    var b = new Ext.Net.Button{
                        ID = this.ID + "_ValueButton",
                        Text = "Show field's value"
                    };
    
                    b.DirectEvents.Click.Event += new ComponentDirectEvent.DirectEventHandler(ShowValueClick);
                    
                    this.Buttons.Add(b);
    
                    b = new Ext.Net.Button
                    {
                        ID = this.ID + "_CloseButton",
                        Text = "Close"
                    };
    
                    b.DirectEvents.Click.Event += new ComponentDirectEvent.DirectEventHandler(CloseClick);
    
                    this.Buttons.Add(b);
                    
                    this.DirectEvents.BeforeClose.Event +=new ComponentDirectEvent.DirectEventHandler(Close_Event);
                    this.DirectEvents.BeforeClose.Type = DirectEventType.Load;
                    this.ResumeScripting();
                }
    
                void  Close_Event(object sender, DirectEventArgs e)
                {
     	            if (this.CloseEvent != null)
                    {
                        this.CloseEvent(this);
                    }
                }
    
                void ShowValueClick(object sender, DirectEventArgs e)
                {
                    Ext.Net.X.Msg.Alert("Value", this.field.Text).Show();
                }
    
                void CloseClick(object sender, DirectEventArgs e)
                {
                    this.Close();
                }
            }
    
            /* Page methods */
            
            private void AddToRecreation(string windowId)
            {
                var ids = this.Session["CreatedWindows"] as System.Collections.Generic.List<string>;    
                
                if(ids == null){
                    ids = new System.Collections.Generic.List<string>(); 
                    this.Session["CreatedWindows"] = ids;  
                }
                
                ids.Add(windowId);
            }
            
            private void RemoveFromRecreation(string windowId)
            {
                var ids = this.Session["CreatedWindows"] as System.Collections.Generic.List<string>;    
                
                if(ids != null){
                    ids.Remove(windowId);
                }            
            }
            
            private static int i = 1;
            protected void ShowWindowClick(object sender, DirectEventArgs e)
            {
                string id = "Window" + i++;   
                this.AddToRecreation(id);
                
                MyWindow w = new MyWindow{ID = id};
                w.CloseEvent +=new MyWindow.DestroyOnClient(window_CloseEvent);
                this.Form.Controls.Add(w);
                w.Render();
            }
    
            void window_CloseEvent(XControl ctrl)
            {
     	        this.RemoveFromRecreation(ctrl.ID);
            }
    
            protected void Page_Init(object sender, EventArgs e)
            {
                var ids = this.Session["CreatedWindows"] as System.Collections.Generic.List<string>;
    
                if (ids != null)
                {
                    foreach (string id in ids)
                    {
                        MyWindow w = new MyWindow { ID = id };
                        this.Form.Controls.Add(w);
                    }
                }
            }
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
            <ext:ResourceManager runat="server" />
            
            <ext:Button runat="server" Text="Show window">
                <DirectEvents>
                    <Click OnEvent="ShowWindowClick" />
                </DirectEvents>
            </ext:Button>
       
        </form>
    </body>
    </html>

    Also, does this same thing apply for why on the dynamic control, the "RegisterClientScriptInclude" method doesn't work to register a .js file when the dynamic control is created?
    During ajax request you can use the following code
    X.Js.Call("Ext.net.ResourceMgr.load", "myJsFile.js");
    or
    X.Js.Call("Ext.net.ResourceMgr.load", "myJsFile.js", "function(){alert('JavaScript file is loaded');}");
  5. #5
    Perfect. Thanks so much! Feel free to mark this as resolved.
    Jason
  6. #6
    Hi Vladimir.
    I used your example (I translated to VB here) and almost all was fine, but I want to contibute to the comunity with one line missing.
    After this line:

    this.Close();
    The next line is neccesary (at least in VB):

    RaiseEvent CloseEvent(Me)
    If that line is not present, then the call to the function named [window_CloseEvent] will never raises.

    Greetings!

Similar Threads

  1. [CLOSED] panel icon missing when dynamically load a user control
    By CarpFisher in forum 2.x Legacy Premium Help
    Replies: 5
    Last Post: Jul 30, 2012, 7:47 AM
  2. [CLOSED] Need a remove button for a dynamically created FileUpload control
    By wisdomchuck in forum 1.x Legacy Premium Help
    Replies: 6
    Last Post: May 22, 2012, 1:40 PM
  3. Replies: 0
    Last Post: Sep 06, 2011, 6:33 PM
  4. [CLOSED] How to clean up dynamically created controls?
    By jchau in forum 1.x Legacy Premium Help
    Replies: 3
    Last Post: Aug 23, 2011, 9:51 AM
  5. [CLOSED] [1.0] Dynamically created control problem
    By galeb in forum 1.x Legacy Premium Help
    Replies: 6
    Last Post: Aug 19, 2010, 7:16 AM

Tags for this Thread

Posting Permissions