如何从 ASP.NET 网站(不是 Web 应用程序)中的用户控件获取父页面

Posted

技术标签:

【中文标题】如何从 ASP.NET 网站(不是 Web 应用程序)中的用户控件获取父页面【英文标题】:How can I get the parent page from a User Control in an ASP.NET Website (not Web Application) 【发布时间】:2010-11-04 23:06:27 【问题描述】:

正如题主所问。

编辑 1

也许有可能在处理请求时将对父页面的引用存储在用户控件中?

【问题讨论】:

没有必要存储引用 - 每个 UserControl 已经公开了一个 Page 属性。 【参考方案1】:
this.Page

或来自任何地方:

Page page = HttpContext.Current.Handler as Page

【讨论】:

【参考方案2】:

我想不出有什么好的理由让用户控件知道它所在的页面,因为用户控件应该不知道它的上下文,并且不管它在哪个页面上,它的行为都是可预测的。

话虽如此,您可以使用this.Page

【讨论】:

这是一个很好的观点。定义明确的用户控件应该完全独立于他们所在的页面。 如果所讨论的应用程序是一个孤立的应用程序,并且所有页面都继承自 BasePage 类,并且您需要访问该 BasePage,那么 this.Page 是一个完全可以接受的解决方案,因为该应用程序中的所有页面都会从该 BasePage 继承,控件将仅为该应用程序定义。 一个很好的用例是访问 Page.Items 集合,该集合可用于存储在 Asp.net 页面处理周期的生命周期中使用的对象。您可以避免在每个用户控件中重新加载常用对象。 在理想情况下这很好,但在许多情况下,控件的某些部分可能具有依赖于调用页面的条件要求。一个很好的例子是,如果在每个页面上都使用了一个控件,并且该控件显示或记录它正在调用的页面(无论出于何种原因,例如内部跟踪、调试,甚至是安全原因)。【参考方案3】:

您可以使用 Parent 属性

如果你需要这个来在页面上找到一个控件,那么你可以使用

Label lbl_Test = (Label)Parent.FindControl("lbl_Test");

【讨论】:

【参考方案4】:

我总是在 System.Web.UI.UserControl 中使用 this.Page。

或者你总是可以对 Parent 进行递归调用,直到你遇到一个 Page 对象。

虽然有点矫枉过正......

protected Page GetParentPage( Control control )

    if (this.Parent is Page)
        return (Page)this.Parent;

    return GetParentPage(this.Parent);

【讨论】:

【参考方案5】:

我发现这样做的方法是创建一个接口,实现该接口,使用this.Page从控件中获取页面,将其转换为接口,然后调用该方法。

【讨论】:

【参考方案6】:

你必须像这样使用 NamingContainer:

       try
        
            if (!string.IsNullOrWhiteSpace(TargetCtrlID))
            
                var ctrl = NamingContainer.FindControl(TargetCtrlID);
                if(ctrl != null)
                    Console.Write("'" + ctrl.ClientID + "'");
            
        
        catch
        

        

【讨论】:

【参考方案7】:

每个控件都有一个父属性,您可以使用它来访问父控件。

protected void Page_Load(object sender, EventArgs e)

  Response.Write(this.Parent.ID);

编辑: 取决于您要存储引用的页面的哪一个生命周期事件以及存储该引用的用途。但是参考总是可用的

【讨论】:

除非 uc 位于页面标签上的另一个 uc 中.....等等 ??【参考方案8】:

在用户控件中创建一个委托,然后从父页面为其分配一个方法。

class MyUserControl : UserControl

   delegate object MyDelegate(object arg1, object arg2, object argN);
   public MyDelegate MyPageMethod;

   public void InvokeDelegate(object arg1, object arg2, object argN)
   
     if(MyDelegate != null)
        MyDelegate(arg1, arg2, argN); //Or you can leave it without the check 
                                      //so it can throw an exception at you.
   


class MyPageUsingControl : Page

   protected void Page_Load(object sender, EventArgs e)
   
     if(!Page.IsPostBack)
        MyUserContorlInstance.MyPageMethod = PageMethod;
   

   public object PageMethod(object arg1, object arg2, object argN)
   
     //The actions I want
   

【讨论】:

【参考方案9】:

从 Web 用户控件写入页面和母版页: 我个人喜欢松散的用户控件,但可以这样做。

母版页:

public partial class Second : System.Web.UI.MasterPage
    
        public void SecondMasterString(string text)
        
            MasterOut.Text += text;
        
    

WebForm1 需要指令:因此页面可以写入母版页

<%@  MasterType VirtualPath="~/DemoFolder/MasterPages/Second.master" %>

方法写入页面和母版页:

public partial class WebForm1 : System.Web.UI.Page
    
    public void SetPageOutput(string text)
        
            // writes to page
            this.PageOut.Text = text;
        

        public void SetMaster(string text)
        
            // writes to Master Page
            this.Master.SecondMasterString(text);
        

用户控件同时写入页面和母版页:

public partial class WebUserControl1 : System.Web.UI.UserControl
    
        protected void Page_Load(object sender, EventArgs e)
        
            LegoLand.DemoFolder.MasterPages.WebForm1 page = (WebForm1)this.Parent.Page;
            page.SetMaster("** From the control to the master");
            page.SetPageOutput("From the control to the page");
        
    

【讨论】:

以上是关于如何从 ASP.NET 网站(不是 Web 应用程序)中的用户控件获取父页面的主要内容,如果未能解决你的问题,请参考以下文章

从 ASP.NET 网站序列化时“无法序列化 EntityReference 对象”,但在 ASP.NET Web 应用程序上工作正常

如何在asp.net c# web应用程序中使用asp.net vb页面

Fiddler 没有从 ASP.NET 网站嗅探 SOAP 流量

ASP.NET Core Web API 应用程序是不是可能出现死锁或应用程序挂起状态

如何在 Web ASP.NET (.NET Framework) 中创建启动文件?

显示从 ASP.NET MVC 中的命令行进程获取的数据