1

Having a large number of issues with this. Essentially attempting to increase performance of a non-working piece currently. The piece consists of a nested dynamic list view setup that i've inherited. It combines many levels of User Controls that are rendered (currently not dynamically) and each display a nested Listview.

This image gives an idea about the structure, but there are more User Controls below the level shown here. (sensitive data) The reason this is painfully slow is that the original code was created with each user control querying the db with a fairly complex query at each level. So on page load, a hideous number of queries are issued.

I'm attempting to dynamically load each user control in on initial expand of the CollapsiblePanelExtender headers, but having some issues with the Update Panels and ViewState for lower levels.

When i attempt to re-generate the dynamically added controls from the session either a data binding issue happens and the fields which are being passed through the levels havent been bound yet, or not repopulated through viewstate or the OnInit method cant find the list view items to iterate through as they havent been bound yet!

Help!

The top level .ascx code

 <asp:ListView ID="fundHoldingListView" runat="server" OnDataBinding="fundHoldingListView_OnDataBinding" OnItemDataBound="fundHoldingListView_OnItemDataBound" OnItemCreated="OnItemCreated">
        <LayoutTemplate>
            <ul class="li-blank collapsible-panel-container">
                <asp:PlaceHolder runat="server" ID="itemPlaceHolder" />
            </ul>
        </LayoutTemplate>
        <ItemTemplate>
            <ajaxToolkit:CollapsiblePanelExtender
                ID="yearlyCollapsableExtender"
                runat="server"
                TargetControlID="yearlyCollapsablePanel"
                ExpandControlID="yearlyPanel"
                CollapseControlID="yearlyPanel"
                Collapsed="True" />
            <li class="li-selectable collapsible-panel">
                <asp:Panel runat="server" ID="yearlyPanel">
                    <h3>
                        <asp:LinkButton ID="linkButton1" runat="server" OnClick="ButtonOnClick" Text='<%# Eval("Value") %>'></asp:LinkButton>
                    </h3>
                </asp:Panel>
            </li>
            <asp:HiddenField ID="yearHiddenField" runat="server" Value='<%# Eval("Value") %>' />
            <asp:Panel runat="server" ID="yearlyCollapsablePanel">
                <asp:UpdatePanel ID="UpdatePanelTimeLineitem" UpdateMode="Conditional" ChildrenAsTriggers="false" runat="server"  EnableViewState="True">
                    <Triggers>
                        <asp:AsyncPostBackTrigger ControlID="linkButton1" />
                    </Triggers>
                    <ContentTemplate>
                        <asp:PlaceHolder runat="server" ID="PlaceHolder1"></asp:PlaceHolder>
                    </ContentTemplate>
                </asp:UpdatePanel>
                <%--   <custom:MonthlyHoldings ID="yearUserControl" runat="server" Year='<%# Eval("Key") %>' MonthlyClientId="<%# ClientIdAutoCompleteLabel.Text %>">
                        </custom:MonthlyHoldings>--%>
            </asp:Panel>
        </ItemTemplate>
    </asp:ListView>

The code behind

/// <summary>
    /// The time line.
    /// </summary>
    public partial class TimeLine : UserControl
    {
        /// <summary>
        /// The control list id.
        /// </summary>
        private const string ControlListId = "CONTROL_LIST";

        /// <summary>
        /// Gets or sets the dynamic controls.
        /// </summary>
        public Dictionary<string, string> DynamicControls
        {
            get
            {
                return (Dictionary<string, string>)Session[ControlListId];
            }

            set
            {
                this.Session[ControlListId] = value;
            }
        }

        /// <summary>
        /// The on init.
        /// </summary>
        /// <param name="e">
        /// The e.
        /// </param>
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            if (!this.IsPostBack)
            {
                this.DynamicControls = new Dictionary<string, string>();
            }
            else
            {
                var controls = this.DynamicControls;

                foreach (var listViewDataItem in this.fundHoldingListView.Items)
                {
                    foreach (var control in controls)
                    {
                        if (listViewDataItem.ID == control.Key)
                        {
                            var controlToAdd = (MonthlyHoldings)LoadControl("/UserControls/MonthlyHoldings.ascx");
                            controlToAdd.ID = control.Value;

                            var placeholder = (PlaceHolder)listViewDataItem.FindControl("PlaceHolder1");

                            placeholder.Controls.Add(controlToAdd);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// The page_ load.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        protected void Page_Load(object sender, EventArgs e)
        {

            this.ClientIdAutoCompleteLabel.Text = "17"; // hard coded value to test

            this.fundHoldingListView.DataBind();
        }

        /// <summary>
        /// The fund holding list view_ on data binding.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        protected void fundHoldingListView_OnDataBinding(object sender, EventArgs e)
        {
            using (var ds = new DataContext())
            {
                this.fundHoldingListView.DataSource =
                    ds.HoldingValueByDates
                        .Where(x => x.ClientPortfolioHolding.ClientPortfolio.ClientId == Convert.ToInt32(this.ClientIdAutoCompleteLabel.Text))
                        .GroupBy(x => x.HoldingDate.Year)
                        .Select(x => new Year { Value = x.Key })
                    .Union(ds.ClientPortfolioHoldings
                        .Where(x => x.ClientPortfolio.ClientId == Convert.ToInt32(this.ClientIdAutoCompleteLabel.Text))
                        .Where(x => x.MaturityDate <= DateTime.Now.Date)
                        .Where(x => x.DisposedOn == null || x.DisposedOn > DateTime.Now.Date)
                        .GroupBy(x => x.MaturityDate.Value.Year)
                        .Select(x => new Year { Value = x.Key }))
                        .OrderByDescending(x => x.Value).ToList();
            }
        }

        /// <summary>
        /// The button on click.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        protected void ButtonOnClick(object sender, EventArgs e)
        {
            var linkButton = (LinkButton)sender;
            var listItem = (ListViewItem)linkButton.NamingContainer;

            if (this.ViewState[listItem.ID] == null)
            {
                this.AddMonthlyHoldings(listItem);
            }
        }

        /// <summary>
        /// The add monthly holdings.
        /// </summary>
        /// <param name="listItem">
        ///     The list item.
        /// </param>
        private void AddMonthlyHoldings(ListViewItem listItem)
        {
            var updatePanel = (UpdatePanel)listItem.FindControl("UpdatePanelTimeLineitem");
            var placeholder = (PlaceHolder)listItem.FindControl("PlaceHolder1");
            var hiddenFieldYear = (HiddenField)listItem.FindControl("yearHiddenField");
            var control = (MonthlyHoldings)LoadControl("/UserControls/MonthlyHoldings.ascx");

            control.ID = Guid.NewGuid().ToString();

            control.MonthlyClientId = this.ClientIdAutoCompleteLabel.Text;
            control.Year = hiddenFieldYear.Value;

            placeholder.Controls.Add(control);

            control.DataBind();
            updatePanel.Update();

            this.DynamicControls.Add(listItem.ID, control.ID);
        }
    }

Second level .ascx

<asp:ListView runat="server" ID="monthlyListView" OnDataBinding="monthlyListView_OnDataBinding" OnItemDataBound="monthlyListView_OnItemDataBound">
    <LayoutTemplate>
        <ul class="li-blank collapsible-subpanel-container">
            <asp:PlaceHolder runat="server" ID="itemPlaceHolder" />
        </ul>
    </LayoutTemplate>
    <ItemTemplate>
        <ajaxToolkit:CollapsiblePanelExtender
            ID="monthlyCollapsableExtender"
            runat="server"
            TargetControlID="monthlyCollapsablePanel"
            ExpandControlID="monthlyPanel"
            CollapseControlID="monthlyPanel"
            Collapsed="True" />
        <li class="li-selectable collapsible-subpanel">
            <asp:Panel runat="server" ID="monthlyPanel">
                <h4>
                    <asp:LinkButton ID="linkButton2" runat="server" OnClick="ButtonOnClick" Text='<%# CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(Convert.ToInt32(Eval("Key")))%>'></asp:LinkButton>
                </h4>
            </asp:Panel>
        </li>

        <asp:HiddenField ID="MonthHiddenField" runat="server" Value='<%# Eval("Key") %>' />
        <asp:HiddenField ID="YearHiddenField" runat="server" Value='<%# Year %>' />
        <asp:HiddenField ID="ClientIdHiddenField" runat="server" Value='<%# MonthlyClientId %>' />

        <asp:Panel runat="server" ID="monthlyCollapsablePanel">
            <asp:UpdatePanel ID="UpdatePanelMonthlyHoldings" UpdateMode="Conditional" ChildrenAsTriggers="false" runat="server" EnableViewState="True">
                <Triggers>
                    <asp:AsyncPostBackTrigger ControlID="linkButton2" />
                </Triggers>
                <ContentTemplate>
                    <asp:PlaceHolder runat="server" ID="Placeholder2"></asp:PlaceHolder>
                </ContentTemplate>
            </asp:UpdatePanel>
            <%--<uc:HoldingDates ID="holdingsUserControl" runat="server" Month='<%# Eval("Key") %>' Year='<%# Year %>' HoldingDatesClientId='<%# MonthlyClientId %>'></uc:HoldingDates>--%>
        </asp:Panel>
    </ItemTemplate>
</asp:ListView>
M05Pr1mty
  • 731
  • 9
  • 29

0 Answers0