Вам на самом деле нужно больше информации, чем плоскость IEnumerable
дает Вам? Просто бросьте его к этому и используйте foreach
с ним. Я сталкиваюсь точно с той же ситуацией в некоторых битах Буферов Протокола, и я нашел, что кастинг к IEnumerable
(или IList
для доступа к ней как список) работает очень хорошо.
Niels,
Leverage reflection (as suggested by JDunkerley) is one approach to the problem. Another you might consider is implementing an interface:
this.Page.Master
via the interface type.This is a better OO approach, leads to less coupling, and will certainly perform better than runtime reflection.
I hope this helps!
Вы должны сначала привести this.Page.Master, поскольку свойство Master страницы имеет тип System.Web.UI.MasterPage.
например
((MyMaster)this.Page.Master).MyFunction();
Вы можете проверить тип основной главной страницы, добавив свойство к коду, находящемуся за пользовательским элементом управления:
public string MType
{
get { return this.Page.Master.GetType().FullName; }
}
, и распечатать результат в разметке пользовательского элемента управления, например, добавить эту строку, чтобы распечатать ее как комментарий в исходном коде:
<!-- <%= MType %> //-->
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?
Дж. Данкерли прав. Но позвольте мне объяснить, как разделить его с помощью 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 позаботится обо всем остальном.
Ура