Я работаю над сайтом, который должен поддерживать два или более внешнего вида с возможностью изменения во время выполнения. Я надеялся, что смогу обработать изменение с помощью переключателя CSS, но похоже, что мне нужно будет использовать разные мастер-страницы для каждого дизайна.
Итак, как лучше всего установить главную страницу во время выполнения? Page.MasterPageFile можно установить только в событии Page.OnPreInit. Похоже, что решения заключаются в том, чтобы все мои страницы унаследовали от общей базы, которая обрабатывает событие PreInit, или использовать HttpModule, который это делает.
Любой совет?





Как насчет того, чтобы вместо двух разных главных страниц иметь одну главную страницу, которая динамически загружает различные пользовательские элементы управления и HTML-литералы содержимого?
Я делал это раньше, я делал именно то, что вы описали (все страницы были унаследованы от настраиваемой страницы с событием OnPreInit). Также у меня был собственный Application_PreRequestHandlerExecute в моем Global.asax.cs для настройки Page.StyleSheetTheme для внесения изменений изображения / css, которые не требовали другой главной страницы.
Достаточно легко обработать PreInit и вставить одну строку кода, необходимую для загрузки правильной мастер-страницы.
this.Page.MasterPageFile = "~/default.master";
В отсутствие какой-либо веской причины не идти по этому пути, я бы поступил так, независимо от того, где вы обрабатываете PreInit.
Мне любопытно, что решает, как должна выглядеть страница? Это пользователь нажимает кнопку, чтобы изменить тему? Основан ли он на URL-адресе, который использовался для перехода на сайт?
Код программной части поддерживается на мастер-страницах, поэтому вы можете добавить логику в свою единую мастер-страницу, чтобы решить, что следует отображать.
Я видел, как несколько сайтов устанавливали файлы cookie на основе щелчков пользователя (для изменения размера шрифта или ширины страницы), а затем применяли разные файлы CSS в зависимости от значения этих файлов cookie. Если файл cookie отсутствует, отобразите внешний вид по умолчанию.
Обновлено:
Еще одна мысль, если вы просто пытаетесь отключить CSS, - это настроить тег стиля для запуска на сервере и назначить ему свойства во время выполнения. И снова это потребует использования одной главной страницы и помещения кода программной части главной страницы, возможно, в обработчике событий PreInit.
Поскольку я никогда не реализовывал это решение, я не уверен, что все
tag has to run at the server or not.
<html>
<head id = "Head" runat = "server">
<style id = "StylePlaceholder" runat = "server" type = "text/css"></style>
</head>
Я чувствую твою боль. Я безуспешно искал проблему в течение часа (если не больше). Когда у вас сотни страниц, это не просто краткий ответ, когда можно сказать «просто вызовите его из PreInit на каждой странице». Но потом я понял, что трачу больше времени на поиск решения, чем на то, чтобы просто делать это на каждой странице.
Однако я хотел установить MasterPageFile на основе свойства Profile, чтобы на каждую страницу приходилось около 5 строк кода, а это кошмар ремонтопригодности. И вообще, «не повторяйся», да?
Поэтому я создал метод расширения в модуле в папке App_Code, чтобы сделать его проще и удобнее в обслуживании.
Public Module WebFunctions
<System.Runtime.CompilerServices.Extension()> _
Public Sub SetMaster(ByVal page As Page)
Dim pb As ProfileCommon = DirectCast(HttpContext.Current.Profile, ProfileCommon)
If pb IsNot Nothing Then
page.MasterPageFile = pb.MasterPage
End If
End Sub
End Module
И затем в PreInit каждой страницы я просто вызываю это:
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
Me.SetMaster()
End Sub
Наследуйте все ваши страницы от базового класса, например
public class PageBase : System.Web.UI.Page
{
public PageBase()
{
this.PreInit += new EventHandler(PageBase_PreInit);
}
void PageBase_PreInit(object sender, EventArgs e)
{
this.MasterPageFile = "~/MyMasterPage.Master";
}
}