如何在运行时通过编程更改ASP Web应用程序的主题(而不是页面)?

5
我正在学习ASP.net,并且一直在尝试使用主题和母版页。我决定更改网站的主题,并使用web.config解决方案(将主题添加到web.config)。现在我想做的是能够根据用户和用户选择的主题来更改主题。
我找不到任何教程,它们似乎都展示如何更改单独的内容页,但我想更改整个网站的主题。
你该如何以最简单的方式做到这一点?我目前没有连接到数据库,只是为了练习 :)
此致敬礼

主题、母版页、内容页和 web.config 是 asp.net 而不是经典的 asp。已编辑您的标签。 - Tim B James
网络上有很多例子,这里是其中一个链接:http://www.asp.net/web-forms/videos/how-do-i/how-do-i-create-user-selectable-themes-for-a-web-site。我建议你可以四处搜索和查找,微软已经发布了相当多的示例。 - John
谢谢,我忘了那个 :) - Iris Classon
这个方法可行,但我必须将控件名称硬编码,因为他使用的代码会导致空引用异常...你有任何想法吗?(我下载了他的代码进行了双重检查,得到了同样的问题)public class BasePage : Page { public BasePage() { } protected override void OnPreInit(EventArgs e) { base.OnPreInit(e); if (Request.Form != null && Request.Form.Count > 0) { this.Theme = Request.Form[this.Master.FindControl("DropDownList1").UniqueID]; } } } - Iris Classon
3个回答

2
创建一个基础页面,所有的页面都从该页面继承,并在OnPreInit事件中设置主题:
public class ThemePage : System.Web.UI.Page
{
    protected override void OnPreInit(EventArgs e)
    {
        SetTheme();            

        base.OnPreInit(e);
    }

    private void SetTheme()
    {
        this.Theme = ThemeSwitcher.GetCurrentTheme();
    }
}

以下是ThemeSwitcher实用类,它处理获取/保存当前主题和列出主题。由于您说您不使用数据库,因此可以使用Session:
public class ThemeSwitcher
{
    private const string ThemeSessionKey = "theme";

    public static string GetCurrentTheme()
    {
        var theme = HttpContext.Current.Session[ThemeSessionKey]
            as string;

        return theme ?? "Default";
    }

    public static void SaveCurrentTheme(string theme)
    {
        HttpContext.Current.Session[ThemeSessionKey]
            = theme;
    }

    public static string[] ListThemes()
    {
        return (from d in Directory.GetDirectories(HttpContext.Current.Server.MapPath("~/app_themes"))
                select Path.GetFileName(d)).ToArray();
    }
}

您需要一个页面来更改主题。在后台添加以下代码的下拉列表:

public partial class _Default : ThemePage
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            BindData();
        }
    }

    private void BindData()
    {
        var currentTheme = ThemeSwitcher.GetCurrentTheme();

        foreach (var theme in ThemeSwitcher.ListThemes())
        {
            var item = new ListItem(theme);
            item.Selected = theme == currentTheme;
            ddlThemes.Items.Add(item);
        }
    }

    protected void ddlThemes_SelectedIndexChanged(object sender, EventArgs e)
    {
        ThemeSwitcher.SaveCurrentTheme(ddlThemes.SelectedItem.Value);
        Response.Redirect("~/default.aspx");
    }       
}

您可以在此处下载示例应用程序:链接

1
谢谢你提供的代码,它是唯一有效的,我尝试了所有上面的教程!哇! :) - Iris Classon

1

我曾经看到过这样的做法,通过从基础页面继承所有页面

    public partial class _Default : BasePage

在基本页面类中设置主题。

public class BasePage : System.Web.UI.Page
{
  protected override void OnPreInit(EventArgs e)
  {
       base.OnPreInit(e);
       Page.Theme = //Your theme;
  }
}

+1 在调用 base.OnPreInit(e) 之前,您应该设置主题。根据 MSDN 的说明,“必须在 PreInit 事件之前设置 Theme 属性;在 PreInit 事件之后设置 Theme 属性将导致 InvalidOperationException 异常。” - Lloyd
在发布之前,我查看了 http://msdn.microsoft.com/en-us/library/ie/tx35bd89.aspx 。这最近有变化吗?或者 MSDN 的信息存在冲突。 - PMC
这是一篇有趣的文章,它说:“在” PreInit 事件之后应用页面个性化和主题。PreInit 事件是页面生命周期早期可以访问的事件。在 PreInit 事件之后,加载个性化信息和页面主题(如果有)。 - Lloyd
Page_PreInit方法会在OnPagePreInit之前被调用吗?https://dev59.com/P1DTa4cB1Zd3GeqPIVzb - Lloyd
我会尝试一下并告诉您结果 :) - Iris Classon
我的错误,文章中确实提到了Page_PreInit,就像你所说的那样,我只是看到了PreInit并做出了假设,糟糕。 - PMC

1

Leniel,这些教程是关于页面的,而不是整个网站。但无论如何,还是非常感谢您 :) - Iris Classon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接