我正在开发一个需要能够支持两种或多种外观的网站,在运行时可以更改。我希望能够使用 CSS 开关来处理更改,但看起来我需要为每个设计使用不同的母版页。
那么,在运行时设置母版页的最佳方法是什么?Page.MasterPageFile 只能在 Page.OnPreInit 事件中设置。看起来解决方案是让我的所有页面都从处理 PreInit 事件的公共基础继承,或者使用执行此操作的 HttpModule。
有什么建议吗?
我正在开发一个需要能够支持两种或多种外观的网站,在运行时可以更改。我希望能够使用 CSS 开关来处理更改,但看起来我需要为每个设计使用不同的母版页。
那么,在运行时设置母版页的最佳方法是什么?Page.MasterPageFile 只能在 Page.OnPreInit 事件中设置。看起来解决方案是让我的所有页面都从处理 PreInit 事件的公共基础继承,或者使用执行此操作的 HttpModule。
有什么建议吗?
我以前做过一次,我完全按照你的描述做了(使所有页面都继承自带有 OnPreInit 事件的自定义页面)。此外,我在 Global.asax.cs 中有一个自定义 Application_PreRequestHandlerExecute 用于设置 Page.StyleSheetTheme 以进行不需要不同母版页的图像/css 更改。
与其拥有两个不同的母版页,不如拥有一个动态加载不同用户控件和内容 HTML 文字的母版?
我感觉到你的痛苦。我搜索了大约一个小时(如果不是更多)来解决这个问题,但没有成功。当您有数百页时,说“只需在每一页上从 PreInit 调用它”不仅仅是一个简单的回答。但后来我意识到我花在寻找解决方案上的时间比在每一页上都花更多的时间。
但是,我想根据 Profile 属性设置 MasterPageFile,因此每页大约需要 5 行代码,这是可维护性的噩梦。无论如何,“不要重复自己”,对吗?
因此,我在 App_Code 文件夹中的一个模块中创建了一个 Extension 方法,以使其更容易和更易于维护。
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
处理 PreInit 并插入加载正确母版页所需的一行代码很容易。
this.Page.MasterPageFile = "~/default.master";
在没有一些令人信服的理由不走这条路的情况下,这就是我要做的,不管你在哪里处理 PreInit。
我很好奇是什么决定了页面的外观?是用户单击按钮来更改主题吗?它是否基于用于访问该站点的 URL?
母版页支持代码隐藏,因此您可以在一个母版页中放置一些逻辑来决定应该显示什么。
我见过几个网站根据用户点击设置 cookie(以更改字体大小或页面宽度),然后根据这些 cookie 的值应用不同的 CSS 文件。如果不存在 cookie,则显示默认外观。
编辑:
这里的另一个想法是,如果您只是尝试切换 CSS,则将样式标签设置为在服务器上运行,并在运行时为其分配属性。再次,这将需要使用单个母版页,并将代码放在母版页的代码隐藏中,可能在 PreInit 事件处理程序中。
由于我从未实施过此解决方案,我不确定整个 <HEAD> 标记是否必须在服务器上运行。
<html>
<head id="Head" runat="server">
<style id="StylePlaceholder" runat="server" type="text/css"></style>
</head>
从基类继承所有页面,例如
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";
}
}