ASP.NET:通过UserControl调用MasterPage中的函数

发布于 2024-08-05 07:27:07 字数 207 浏览 5 评论 0原文

从页面中的 MasterPage 调用函数非常简单,但如何为 UserControl 调用它:

添加 <%@ MasterType VirtualPath="~/MasterPage.master" %>,不会不适用于用户控件。

所以 this.Page.Master.MyFunction() 失败:(

Calling a function from the MasterPage in a Page is quite straigt forward but how do I call it for a UserControl:

Adding <%@ MasterType VirtualPath="~/MasterPage.master" %>, doesn't work on UserControls.

So this.Page.Master.MyFunction() fails :(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

扶醉桌前 2024-08-12 07:27:07

您必须首先将 this.Page.Master 转换为

例如,

((MyMaster)this.Page.Master).MyFunction();

您可以通过向用户控件后面的代码添加属性来检查底层母版页的类型:

    public string MType
    {
        get { return this.Page.Master.GetType().FullName; }
    }

并在用户控件标记中打印结果,例如添加此行以使其作为源中的注释打印出来代码:

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

You have to cast the this.Page.Master first as the Master property of the Page is of type System.Web.UI.MasterPage.

e.g.

((MyMaster)this.Page.Master).MyFunction();

You could check the type of the underlying master page by adding a property to the code behind of the user control:

    public string MType
    {
        get { return this.Page.Master.GetType().FullName; }
    }

and print the result out in the User control markup, e.g. add this line to make it print out as a comment in the source code:

<!-- <%= MType %> //-->
剑心龙吟 2024-08-12 07:27:07

Niels,

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

  1. 创建一个包含您的方法的接口。
  2. 在母版页中实现接口
  3. 从您的控件中,通过接口类型引用 this.Page.Master
  4. 调用你的方法。

这是一种更好的面向对象方法,可以减少耦合,并且肯定会比运行时反射表现得更好。

我希望这有帮助!

Niels,

Leverage reflection (as suggested by JDunkerley) is one approach to the problem. Another you might consider is implementing an interface:

  1. Create an interface that includes your method.
  2. Implement the interface in your master page
  3. From your control, reference this.Page.Master via the interface type.
  4. Call your method.

This is a better OO approach, leads to less coupling, and will certainly perform better than runtime reflection.

I hope this helps!

决绝 2024-08-12 07:27:07

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

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

您到底想在控制范围内完成什么?

You are couppling your code very thighly if you call a function on the masterpage from within your user control.

The Control can only be used on pages that are based on that master. I think this is usually a bad design, and it will violate at least the law of demeter.

What exactly do you want to accomplish in your control?

躲猫猫 2024-08-12 07:27:07

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();
}

确保在控件的接口 (IControlView) 中声明“EventFired”事件并在控件中实现。然后,要影响 master(调用其方法),您所要做的就是触发此事件,MVP + PageContoller 将处理其余的事情。

干杯

JDunkerley has it right. But allow me to explain how to decouple it using MVP so you can work toward avoiding the design issue Heiko Hatzfeld is talking about.

Basically, implement the MVP pattern for both your control and your master page. See here for instructions on how to do that. Declare the method you want to call in the master's interface (IMasterView). Next create a class that will control the relationship between the two components; we'll call it the PageController class. Place an instance of this class in request state for each request by adding the following line to global.asax.cs:

/* global.asax.cs */
protected void Application_BeginRequest(object sender, EventArgs e)
{
    // ...
    HttpContext.Current.Items["Controller"] = new PageController();
    // ...
}

You can then access this instance from each of the presenters (master and control) via the following line of code:

var controller = HttpContext.Current.Items["Controller"] as PageController;

You can then implement an event or some other mechanism to allow the control to invoke the method on the master in a decoupled manner through this shared object. For example:

/* 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();
}

Make sure the "EventFired" event is declared in your control's interface (IControlView) and implemented in the control. Then all you have to do to affect the master (call its method), is fire this event and the MVP + the PageContoller will take care of the rest.

Cheers

冷月断魂刀 2024-08-12 07:27:07

我无法得到上述答案,所以这对我有用:

您想从用户控件引用母版页属性。

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

public string BodyClass
{
    set
    {
        this.masterBody.Attributes.Add("class", value);
    }
}

现在在用户控件 ASCX 文件中添加对母版页的引用,如下所示:

<%@ Register Src="~/Source/MasterPages/Main.master" TagPrefix="MSTR" TagName="MasterPage" %>

在后面的代码中(在我的例子中为 C#)您有以下代码:

Main masterPage = (Main)this.Page.Master;
masterPage.BodyClass = "container";

然后 您的用户控件上方的母版页将无法找到母版页类。

I couldn't get the above answers to work, so here is what worked for me:

You want to reference a master page property from a user control.

Firstly, your master page will have a public property like so :

public string BodyClass
{
    set
    {
        this.masterBody.Attributes.Add("class", value);
    }
}

Now add a reference to the master page in the user control ASCX file like so :

<%@ Register Src="~/Source/MasterPages/Main.master" TagPrefix="MSTR" TagName="MasterPage" %>

Then in the code behind (C# in my case) you have this code :

Main masterPage = (Main)this.Page.Master;
masterPage.BodyClass = "container";

Without the reference to the master page above your user control will not be able to find the master page class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文