使用控件管理器减少递归Page.FindControl的使用-不知道是否可能?

问题描述

| 我有在网络仪表板上动态添加和重新创建的控件。我一直在尝试减少Page.FindControl的使用。我发现在Page上使用大量动态创建的内容的速度很慢。 在尝试中,我创建了一个RegenerationManager单例,该单例现在负责重新生成动态内容。每当它重新生成对象时,都会将该对象存储在列表中。该管理器根据对象类型保留这些列表中的几个。 稍后,当我需要通过ID来获取对象时,请转到再生管理器以检索该对象。 例如:
public class RegenerationManager
{
    private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

    private static readonly RegenerationManager instance = new RegenerationManager();
    private RegenerationManager() { }

    public static RegenerationManager Instance
    {
        get { return instance; }
    }

    public List<CormanTradPane> RegeneratedPanes = new List<CormanTradPane>();
    public List<CormanTradDockZone> RegeneratedDockZones = new List<CormanTradDockZone>();

    /// <summary>
    /// Recreates all the dynamically made DockZones.
    /// </summary>
    public void RegenerateDockZones()
    {
        Logger.Info(\"Regenerating dock zones.\");
        foreach (keyvaluePair<string,RadDockZonesetting> dockZonestate in RadControlManager.GetStates<SerializableDictionary<string,RadDockZonesetting>>())
        {
            try
            {
                RadDockZonesetting dockZonesetting = dockZonestate.Value as RadDockZonesetting;
                Logger.Info(String.Format(\"Loading state data for dock zone with setting ID: {0}\",dockZonesetting.ID));
                CormanTradDockZone dockZone = new CormanTradDockZone(dockZonesetting);
                RegeneratedDockZones.Add(dockZone);
                CormanTradPane pane = RegeneratedPanes.First(regeneratedPane => regeneratedPane.ID == dockZonesetting.ParentID);
                pane.Controls.Add(dockZone);
            }
            catch (Exception exception)
            {
                Logger.ErrorFormat(\"Error regenerating dock zones. Reason: {0}\",exception.Message);
            }
        }
    }
}

/// <summary>
/// Creates the RadDock + Contents when dropping a graph onto the page.
/// </summary>
/// <param name=\"sender\"> The RadListBox with an element being dropped from inside it. </param>
/// <param name=\"e\"> information about the drop such as target and what is being dropped. </param>
protected void RadListBox_Dropped(object sender,RadListBoxDroppedEventArgs e)
{
    CormanTradDockZone dockZoneOld = Utilities.FindControlRecursive(Page,e.HtmlElementID) as CormanTradDockZone;
    CormanTradDockZone dockZone = RegenerationManager.Instance.RegeneratedDockZones.First(regeneratedDockZone => regeneratedDockZone.ID == e.HtmlElementID);

    if (!object.Equals(dockZone,null) && !dockZone.Docks.Any())
    {
        RadSlidingPane slidingPane = ((sender as RadListBox).Parent as RadSlidingPane);
        CormantReport report = new CormantReport(int.Parse(e.sourceDragItems[0].Value),e.sourceDragItems[0].Text,slidingPane.Title);
        CormanTradDock dock = new CormanTradDock(report);
        dock.CreateContent();
        dockZone.Controls.Add(dock);
    }
}
现在,我认为这是一个很好的解决方案,但是经过测试,我发现添加到dockZone的CormanTradDock不会显示在我的Web仪表板上,但是如果我将其添加到dockZoneOld,它会显示出来。 看着这两个对象,我没有注意到这两个对象有任何不同之处,但是显然有一些东西。 我的想法有可能实现吗? 编辑:我怀疑问题是与Telerik的控件有关。我有一个想法,我会稍后再报告。 编辑:这确实是Telerik的事情。我需要浏览他们的RadDockLayout.RegisteredDockZone \的列表,而不是保留自己的托管列表。     

解决方法

        这里要做的关键是调试代码,并在此行上设置一个断点:
CormantRadDockZone dockZone = RegenerationManager.Instance.RegeneratedDockZones.First(regeneratedDockZone =>regeneratedDockZone.ID == e.HtmlElementID);`
然后对“ 2”的内容进行快速监视,以查看该列表中是否包含任何元素。因此,这里我们要检查基础知识-列表中是否有任何项目? 如果其中有项目,则需要弄清楚为什么您要查找的特定元素不在列表中。该列表必须有效,因为其中有项目,但是尚未添加此特定元素。 如果您100%将该元素添加到列表中,则可能与您使用的单例模式有关。老实说,对我来说看起来不错,但我不是单例设计模式的专家。 抱歉,我没有更多帮助。 编辑: 可能有帮助的一件事是对类进行一些重构:
private IList<CormantRadPane> _regeneratedPanes;
private IList<CormantRadDockZone> _regeneratedDockZones;

    public IList<CormantRadPane>  RegeneratedPanes
    {
        get
        {
        if(_regeneratedPanes == null)
                {
                    _regeneratedPanes = new List<CormantRadPane>()
                }

                return _regeneratedPanes
            }
        }

        public IList<CormantRadDockZone> RegeneratedDockZones
        {
            get
            {
                if(_regeneratedDockZones == null)
                {
                    _regeneratedDockZones = new List<CormantRadDockZone>()
                }

                return _regeneratedDockZones
            }
        }
在这里,我使用属性来返回列表,而不是使人们直接访问列表成员。 这可以帮助您调试代码。