Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在需要时创建一个静态类;小心使用Page.FindControl。建议?_C#_Asp.net_Ajax - Fatal编程技术网

C# 在需要时创建一个静态类;小心使用Page.FindControl。建议?

C# 在需要时创建一个静态类;小心使用Page.FindControl。建议?,c#,asp.net,ajax,C#,Asp.net,Ajax,我有一门课叫LayoutManager。此类的目的是保存对当前在我的ASP.NET页面上表示的对象的引用。我最初创建这个类是因为我对它感到非常沮丧。我的挫折有两方面: Page.FindControl()在其本机实现中仅搜索页面的直接子级。为了在页面上找到任何给定的控件,需要递归实现。出于性能原因,我反对这样做 为了调用Page.FindControl,我的所有相关类都需要知道Page的名称。这似乎是一个很大的耦合,我试图通过中产阶级来缓解这种耦合 因此,我创建了如下所示的类。我刚刚看到我的

我有一门课叫LayoutManager。此类的目的是保存对当前在我的ASP.NET页面上表示的对象的引用。我最初创建这个类是因为我对它感到非常沮丧。我的挫折有两方面:

  • Page.FindControl()在其本机实现中仅搜索页面的直接子级。为了在页面上找到任何给定的控件,需要递归实现。出于性能原因,我反对这样做
  • 为了调用Page.FindControl,我的所有相关类都需要知道Page的名称。这似乎是一个很大的耦合,我试图通过中产阶级来缓解这种耦合
因此,我创建了如下所示的类。我刚刚看到我的实现是多么糟糕。为了简化此示例,我删除了在不同对象上执行相同工作的方法:

/// <summary>
/// This class manages controls which are present on the page.
/// Whenever a control is created it notifies this manager that it has been
/// created (inside of its constructor). At that point, you can use this
/// manager to find controls on the dashboard. 
/// The only other option is to use Page.FindControl, but its pretty broken and slow.
/// </summary>
public class LayoutManager
{
    private static readonly ILog _logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

    private static readonly LayoutManager _instance = new LayoutManager();
    private LayoutManager() { }

    public static LayoutManager Instance
    {
        get { return _instance; }
    }

    //HashSets for efficiency. As long as order doesn't matter, use these.
    private HashSet<CormantRadDock> _registeredDocks;

    public RadMultiPage MultiPage { get; set; }
    public CormantTimer Timer { get; set; }
    public DashboardUpdatePanel MultiPageUpdatePanel { get; set; }
    public CormantRadTabStrip TabStrip { get; set; }
    public RadListBox TabsListBox { get; set; }
    public UpdatePanel GlobalSettingsUpdatePanel { get; set; }

    public HashSet<CormantRadDock> RegisteredDocks
    {
        get
        {
            if (Equals(_registeredDocks, null))  
                _registeredDocks = new HashSet<CormantRadDock>();
            return _registeredDocks;
        }
    }

    public CormantRadDock GetDockByID(string dockID)
    {
        CormantRadDock dock = RegisteredDocks.FirstOrDefault(registeredZone => dockID.Contains(registeredZone.ID));

        if (Equals(dock, null))
            _logger.ErrorFormat("Did not find dock: {0}", dockID);
        else
            _logger.DebugFormat("Found dock: {0}", dockID);

        return dock;
    }
}

在您真正尝试之前,我不会担心递归扫描程序的性能。如果你需要的话,我这里有:


(寻找
ControlHelper
类,现在它甚至可以是一个带有扩展方法的静态类)

我认为您根本不应该害怕使用递归
FindControl()
方法。除非页面深入到无数个层次(它不应该这样),否则递归函数应该能够遍历控件层次结构而不费吹灰之力

简而言之,构建一个递归的
FindControl()
方法。你没有什么可担心的;不要让它静止

编辑

要从外部类获取当前页的句柄,您应该能够执行以下操作:

var page = HttpContext.Current.Handler as Page;
if (page != null)
{
    //found the current page
    //...
}

知道如何从另一个类获取页面句柄吗?我真的不想将我的页面对象传递给任何可能希望找到控件的方法。当然,您应该能够使用
HttpContext.Current.Handler
Word获取页面。这正是我开始使用的解决方案。请参阅我的编辑以确认,但我认为我们现在正走在一条好的道路上。谢谢大家!@SeanAnderson:没问题,而且实现看起来很可靠。我唯一的建议是检查处理程序是否为null,如上面的示例所示。除此之外,它看起来很棒。处理程序何时返回null?
var page = HttpContext.Current.Handler as Page;
if (page != null)
{
    //found the current page
    //...
}