ASP.NET: вызов функции в MasterPage через UserControl
вызов функции из MasterPage на странице довольно прямой, но как я могу вызвать ее для UserControl:
добавлять <%@ MasterType VirtualPath="~/MasterPage.master" %>
, не работает на UserControls.
Так this.Page.Master.MyFunction()
не удается :(
5 ответов
Нильс,
отражение рычагов (как предложил JDunkerley) - это один из подходов к проблеме. Еще можно рассмотреть реализует интерфейс:
- создайте интерфейс, который включает ваш метод.
- реализует интерфейс на главной странице
- из вашего управления, ссылка
this.Page.Master
по типу интерфейса. - вызов ваш метод.
Это лучший подход ОО, водит к меньше соединения, и, безусловно, будет работать лучше, чем runtime reflection.
надеюсь, это поможет!
вы должны бросить это.Страница.Мастер сначала как мастер свойство страницы имеет тип System.Сеть.ПОЛЬЗОВАТЕЛЬСКИЙ ИНТЕРФЕЙС.мастер-страница.
например
((MyMaster)this.Page.Master).MyFunction();
вы можете проверить тип базовой главной страницы, добавив свойство в код позади пользовательского элемента управления:
public string MType
{
get { return this.Page.Master.GetType().FullName; }
}
и распечатать результат в разметке пользовательского элемента управления, например, добавить эту строку, чтобы сделать его распечатать в качестве комментария в исходном коде:
<!-- <%= MType %> //-->
вы очень сильно переворачиваете свой код, если вы вызываете функцию на masterpage из своего пользовательского элемента управления.
элемент управления может использоваться только на страницах, основанных на этом мастере. Я думаю, что это обычно плохой дизайн, и он нарушит, по крайней мере, закон Деметры.
чего именно вы хотите достичь в своем контроле?
JDunkerley имеет это право. Но позвольте мне объяснить, как отделить его с помощью MVP, чтобы вы могли работать над тем, чтобы избежать проблемы дизайна, о которой говорит Хейко Хацифельд.
В основном, реализуйте шаблон MVP как для вашего элемента управления, так и для главной страницы. См.здесь Инструкции о том, как это сделать. Объявите метод, который вы хотите вызвать в главном интерфейсе (IMasterView). Затем создайте класс, который будет контролировать отношения между двумя компонентами; мы будем назовите его классом PageController. Поместите экземпляр этого класса в состояние запроса для каждого запроса, добавив следующую строку в global.асакс.cs:
/* global.asax.cs */
protected void Application_BeginRequest(object sender, EventArgs e)
{
// ...
HttpContext.Current.Items["Controller"] = new PageController();
// ...
}
вы можете получить доступ к этому экземпляру от каждого из ведущих (master и control) через следующую строку кода:
var controller = HttpContext.Current.Items["Controller"] as PageController;
затем вы можете реализовать событие или какой-либо другой механизм, чтобы позволить элементу управления вызывать метод на master развязанным способом через этот общий объект. Для пример:
/* 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 позаботится об остальном.
Ура
Я не мог получить вышеуказанные ответы на работу, поэтому вот что сработало для меня:
вы хотите ссылаться на свойство главной страницы из пользовательского элемента управления.
во-первых, ваша главная страница будет иметь общественную собственность, как так :
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";
без ссылки на главная страница над вашим пользовательским элементом управления не сможет найти класс главной страницы.