ASP.NET: вызов функции в MasterPage через UserControl - PullRequest
6 голосов
/ 18 сентября 2009

Вызов функции из MasterPage на странице довольно прост, но как мне вызвать ее для UserControl:

Добавление <%@ MasterType VirtualPath="~/MasterPage.master" %>, не работает с UserControls.

Итак, this.Page.Master.MyFunction() не удается: (

Ответы [ 5 ]

12 голосов
/ 18 сентября 2009

Сначала необходимо привести к действию this.Page.Master, поскольку свойство Master страницы имеет тип System.Web.UI.MasterPage.

, например

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

Вы можете проверить тип базовой страницы, добавив свойство к коду позади пользовательского элемента управления:

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

и распечатайте результат в разметке пользовательского элемента управления, например, добавьте эту строку, чтобы распечатать ее как комментарий в исходном коде:

<!-- <%= MType %> //-->
7 голосов
/ 18 сентября 2009

Niels,

Рефлексия рычагов (как предложил Дж.Данкерли) является одним из подходов к проблеме. Еще один вариант, который вы могли бы рассмотреть, это реализация интерфейса:

  1. Создайте интерфейс, включающий ваш метод.
  2. Реализация интерфейса на главной странице
  3. Под вашим контролем, ссылка this.Page.Master через тип интерфейса.
  4. Назовите свой метод.

Это лучший ОО-подход, который приводит к меньшей связности и, безусловно, будет работать лучше, чем отражение во время выполнения.

Надеюсь, это поможет!

4 голосов
/ 18 сентября 2009

Вы связываете свой код очень сильно, если вызываете функцию на главной странице из своего пользовательского элемента управления.

Элемент управления можно использовать только на страницах, которые основаны на этом мастере. Я думаю, что это обычно плохой дизайн, и он будет нарушать, по крайней мере, закон Деметры.

Что именно вы хотите достичь в вашем контроле?

1 голос
/ 22 февраля 2012

Я не смог заставить работать приведенные выше ответы, поэтому вот что сработало для меня:

Вы хотите сослаться на свойство главной страницы из пользовательского элемента управления.

Во-первых, ваша главная страница будет иметь общедоступную собственность, например:

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";

Без ссылки на главную страницу выше ваш пользовательский элемент управления не сможет найти класс главной страницы.

1 голос
/ 18 сентября 2009

JDunkerley правильно понял. Но позвольте мне объяснить, как отделить его с помощью MVP, чтобы вы могли избегать проблем с дизайном, о которых говорит Хайко Хатцфельд. ​​

По сути, реализуйте шаблон 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 + PageContoller позаботится об остальном.

* +1015 * Приветствия
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...