C# ASP.NET:通过UserControl调用母版页中的函数

C# ASP.NET:通过UserControl调用母版页中的函数,c#,asp.net,master-pages,asp-usercontrols,C#,Asp.net,Master Pages,Asp Usercontrols,在页面中从母版页调用函数是非常困难的,但是如何为UserControl调用它: 添加,对用户控件无效 因此this.Page.Master.MyFunction()失败:(您必须首先强制转换this.Page.Master,因为页面的属性类型为System.Web.UI.MasterPage e、 g 您可以通过向用户控件的代码隐藏添加属性来检查基础母版页的类型: public string MType { get { return this.Page.Maste

在页面中从母版页调用函数是非常困难的,但是如何为UserControl调用它:

添加
,对用户控件无效


因此
this.Page.Master.MyFunction()
失败:(

您必须首先强制转换this.Page.Master,因为页面的属性类型为System.Web.UI.MasterPage

e、 g

您可以通过向用户控件的代码隐藏添加属性来检查基础母版页的类型:

    public string MType
    {
        get { return this.Page.Master.GetType().FullName; }
    }
并在用户控件标记中打印结果,例如,添加此行以使其在源代码中作为注释打印:

<!-- <%= MType %> //-->

如果从用户控件中调用母版页上的函数,则代码耦合非常紧密

该控件只能用于基于该母版的页面。我认为这通常是一个糟糕的设计,至少会违反德米特定律

在你的控制下,你到底想完成什么

杠杆反射(如JDunkerley所建议的)是解决问题的一种方法,另一种可能是实现接口:

  • 创建包含方法的接口
  • 在母版页中实现该接口
  • 从控件中,通过接口类型引用
    此.Page.Master
  • 调用您的方法
  • 这是一种更好的OO方法,会减少耦合,并且肯定会比运行时反射性能更好


    我希望这会有所帮助!

    JDunkerley说得对。但请允许我解释如何使用MVP将其解耦,以便您可以努力避免Heiko Hatzfeld所谈论的设计问题

    基本上,为控件和母版页实现MVP模式。有关如何实现的说明,请参阅。声明要在母版界面(IMasterView)中调用的方法。接下来创建一个类,该类将控制两个组件之间的关系;我们将其称为PageController类。通过将以下行添加到global.asax.cs,将该类的一个实例置于每个请求的请求状态:

    /* global.asax.cs */
    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        // ...
        HttpContext.Current.Items["Controller"] = new PageController();
        // ...
    }
    
    然后,您可以通过以下代码行从每个演示者(主机和控件)访问此实例:

    var controller = HttpContext.Current.Items["Controller"] as PageController;
    
    然后,您可以实现一个事件或一些其他机制,以允许控件通过此共享对象以解耦的方式调用主机上的方法。例如:

    /* PageController.cs */
    public event EventHandler SomeEvent;
    
    protected virtual void OnSomeEvent(EventArgs e)
    {
        Debug.Assert(null != e);
    
        var handler = this.SomeEvent;
        if (null != handler)
            handler(this, e);
    }
    
    public void FireSomeEvent()
    {
       this.OnSomeEvent(EventArgs.Empty);
    }
    
    /* ControlPresenter.cs */
    public ControlPresenter(IControlView view)
        : base()
    {
        view.EventFired += (sender, e) =>
        {
            var controller = HttpContext.Current.Items["Controller"] as PageController;
            controller.FireSomeEvent();
        };
    }
    
    /* MasterPresenter.cs */
    public MasterPresenter (IMasterView view)
        : base()
    {
        var controller = HttpContext.Current.Items["Controller"] as PageController;
        controller.SomeEvent += (sender, e) => view.MyFunction();
    }
    
    确保“EventFired”事件在控件的界面(IControlView)中声明并在控件中实现。然后,要影响主控(调用其方法)所需做的一切就是触发此事件,MVP+PageConcoller将处理其余事件


    干杯

    我无法在工作中得到上述答案,因此以下是对我有效的方法:

    您希望从用户控件引用母版页属性

    首先,您的母版页将具有如下公共属性:

    public string BodyClass
    {
        set
        {
            this.masterBody.Attributes.Add("class", value);
        }
    }
    
    <%@ Register Src="~/Source/MasterPages/Main.master" TagPrefix="MSTR" TagName="MasterPage" %>
    
    现在在用户控件ASCX文件中添加对母版页的引用,如下所示:

    public string BodyClass
    {
        set
        {
            this.masterBody.Attributes.Add("class", value);
        }
    }
    
    <%@ Register Src="~/Source/MasterPages/Main.master" TagPrefix="MSTR" TagName="MasterPage" %>
    

    如果没有对上面的母版页的引用,您的用户控件将无法找到母版页类。

    我收到一个错误,说它找不到类型或名称空间\u master??您可以尝试在运行时检查母版页的类型。将在一秒钟内更新答案类型为ASP.masterpage\u master,但在compile t中不可用ime。母版页标记中的标记上是否有继承项?我刚刚在ASP.Net网站上尝试过,代码运行良好。很高兴能提供帮助!快乐编码:-)