/// <summary>
        /// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering.
        /// </summary>
        protected override void CreateChildControls()
        {
            if (this.Configuration == null)
                throw new ConfigurationErrorsException(Resources.Ctrl_PropertyConfigurationNotSpecified);

            base.CreateChildControls();

            // create layout panels
            List<KeyValuePair<QueryFieldConfiguration, IEnumerable<IQueryFieldControl>>> queryFieldControlsByConfigurations = new List<KeyValuePair<QueryFieldConfiguration, IEnumerable<IQueryFieldControl>>>();
            foreach (QueryFieldConfiguration queryFieldConfiguration in this.Configuration.Controls)
            {
                IEnumerable<IQueryFieldControl> queryFieldControlsByConfiguration = QueryFieldControlFactory.CreateQueryControls(queryFieldConfiguration);
                queryFieldControlsByConfigurations.Add(new KeyValuePair<QueryFieldConfiguration, IEnumerable<IQueryFieldControl>>(queryFieldConfiguration, queryFieldControlsByConfiguration));
                foreach (IQueryFieldControl queryFieldControl in queryFieldControlsByConfiguration)
                    this.queryFieldControlsByFieldName.Add(new KeyValuePair<IQueryFieldControl, string>(queryFieldControl, queryFieldConfiguration.FieldName));
            }

            IQueryPanelLayout queryPanelLayoutGenerator = SpringContext.Current.GetObject<IQueryPanelLayout>();
            Control queryPanelLayout = queryPanelLayoutGenerator.Create(queryFieldControlsByConfigurations);
            this.Controls.Add(queryPanelLayout);

            IEnumerable<IQueryFieldControl> queryFieldControls = this.queryFieldControlsByFieldName.Select(kvp => kvp.Key);
            QueryFieldControlFactory.AssignQueryFieldControlIDAndIndex(queryFieldControls);

            // create hiddenfield to store all client variables for query field controls.
            StringBuilder queryFieldControlVariablesBuilder = new StringBuilder();
            foreach (IQueryFieldControl queryFieldControl in queryFieldControls)
            {
                if (queryFieldControlVariablesBuilder.Length > 0)
                    queryFieldControlVariablesBuilder.Append(";");

                queryFieldControlVariablesBuilder.AppendFormat("{0}{1}:{2}", WebUtility.QUERY_FIELD_CONTROL_POST_PREFRIX_NAME, queryFieldControl.ControlIndex, queryFieldControl.ClientVariableName);
            }

            this.hiddenFieldQueryFieldControlVariables = new System.Web.UI.WebControls.HiddenField { ID = "HiddenFieldQueryFieldControlVariables" };
            this.hiddenFieldQueryFieldControlVariables.Value = queryFieldControlVariablesBuilder.ToString();
            this.Controls.Add(this.hiddenFieldQueryFieldControlVariables);

            HtmlTable tableButtons = new HtmlTable { ID="ButtonPanel", CellPadding = 0, CellSpacing = 0, Width = "100%" };
            tableButtons.Attributes["class"] = "querypanel-buttons";
            this.Controls.Add(tableButtons);

            HtmlTableRow rowButton = new HtmlTableRow();
            tableButtons.Rows.Add(rowButton);

            HtmlTableCell cellButton = new HtmlTableCell { Align = "center" };
            cellButton.Style["padding-top"] = "6px";
            rowButton.Cells.Add(cellButton);

            this.buttonQuery = new Button { ID = "ButtonQuery", Configuration = new ButtonConfiguration { ButtonRenderType = ButtonRenderTypes.Button, Text = Resources.Ctrl_QueryButtonText } };
            cellButton.Controls.Add(this.buttonQuery);

            HtmlGenericControl buttonSeparator = new HtmlGenericControl("span") { InnerHtml = "    " };
            buttonSeparator.Style["padding-left"] = "2px";
            buttonSeparator.Style["padding-right"] = "2px";
            cellButton.Controls.Add(buttonSeparator);

            this.buttonReset = new Button { ID = "ButtonReset", Configuration = new ButtonConfiguration { ButtonRenderType = ButtonRenderTypes.Button, Text = Resources.Ctrl_ResetButtonText } };
            cellButton.Controls.Add(this.buttonReset);
        }
        private Control CreateButtonContainerControl()
        {
            Panel buttonContainer = new Panel { ID = "AggregatePanelButtonContainer" };
            buttonContainer.Style["padding-top"] = "6px";
            buttonContainer.Style["text-align"] = "center";

            HtmlTable buttonLayoutTable = new HtmlTable { CellPadding = 0, CellSpacing = 0 };
            buttonLayoutTable.Style["margin"] = "auto";
            buttonContainer.Controls.Add(buttonLayoutTable);

            HtmlTableRow buttonLayoutRow = new HtmlTableRow();
            buttonLayoutTable.Rows.Add(buttonLayoutRow);

            HtmlTableCell buttonLayoutCell = new HtmlTableCell("td");
            buttonLayoutRow.Cells.Add(buttonLayoutCell);

            if (this.aggregatePanelConfiguration.SaveButton != null)
            {
                this.ButtonSave = new RapidWebDev.UI.Controls.Button { ID = "ButtonSave", Text = this.aggregatePanelConfiguration.SaveButton.Text ?? Resources.DPCtrl_SaveText, ToolTip = this.aggregatePanelConfiguration.SaveButton.ToolTip };
                this.ButtonSave.Click += new EventHandler(this.ButtonSave_Click);
                buttonLayoutCell.Controls.Add(this.ButtonSave);
                this.updatePanelAggregatePanelWrapper.Triggers.Add(new AsyncPostBackTrigger { ControlID = this.ButtonSave.ID, EventName = "Click" });
                base.SetFormDefaultButton(this.aggregatePanelConfiguration.SaveButton, "ButtonSave");
            }

            if (this.aggregatePanelConfiguration.CancelButton != null)
            {
                buttonLayoutCell.Controls.Add(new HtmlGenericControl("span") { InnerText = " " });

                const string javaScriptBlock = @"if (window.parent.RegisteredGridViewPanelObject) window.parent.RegisteredGridViewPanelObject.HideAggregatePanelWindow(); return false;";
                this.ButtonCancel = new RapidWebDev.UI.Controls.Button() { ID = "ButtonCancel", Text = this.aggregatePanelConfiguration.CancelButton.Text ?? Resources.DPCtrl_CancelText, ToolTip = this.aggregatePanelConfiguration.CancelButton.ToolTip };
                this.ButtonCancel.OnClientClick = javaScriptBlock;
                buttonLayoutCell.Controls.Add(this.ButtonCancel);
                this.updatePanelAggregatePanelWrapper.Triggers.Add(new AsyncPostBackTrigger { ControlID = this.ButtonCancel.ID, EventName = "Click" });
                base.SetFormDefaultButton(this.aggregatePanelConfiguration.CancelButton, "ButtonCancel");
            }

            return buttonContainer;
        }