65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET 中的动态 CSS 样式:一种灵活的方法

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.08/5 (19投票s)

2006年5月6日

CPOL

5分钟阅读

viewsIcon

167589

downloadIcon

1777

一种在 ASP.NET 中实现动态样式设置的灵活方法。该技术强调结构和可扩展性。

Sample Image - ASPNET_Dynamic_Styling.jpg

引言

样式设置是绝大多数 Web 开发人员,如果不是所有 Web 开发人员,都必须面对的任务。许多人可能也遇到过以清晰且灵活的方式设置页面样式的问题,以便能够动态处理不断变化的样式。本文以一种简洁、直接的方式解决了这个问题,并受益于 CSS 和 ASP.NET 提供的关键功能。

问题

假设我有一个网站,它会根据某些条件自动更改其外观和感觉。现在,“自动”这个词有些模糊,但我暂时保留它。您可能希望在节假日有特定的样式,在平常日子有另一种样式,在每个季节有其他的样式,等等……实现这一目标通常的方法是创建一个 ASPX 文件,该文件根据其检查的条件动态生成适当的输出。然后页面会链接到那个动态生成的 CSS,就完成了。这里有什么问题?

  1. 事实是,通过代码生成意味着每次更改都必须重新编译。
  2. 如果我可以摆脱 ASP.NET 运行时,为什么不呢?
  3. 更改网站的外观和感觉不仅需要设计师,还需要程序员的协助。
  4. 我更喜欢简单的文本文件(.css)。

解决方案

我通过使用一些“调味料”的、仍然是旧的 CSS 文件解决了上述问题。主要功能存在于 CSS 本身,这一点很多人都忽略了。CSS 允许您以类似面向对象的方式来解决这个问题。方法如下:

CSS

我们将“主标题”(例如)的通用样式放在一个类中,如下所示:

.MainTitle
{
   text-decoration: underline;
   color: Black;
}

以及我们在 Mode1(可能是夏季)时的“主标题”样式:

.Mode1 .MainTitle
{
    font-size: 16pt;
}

“主标题”的 Mode2 特定样式在此处:

.Mode2 .MainTitle
{
    font-size: 18pt;
}

所以,正如我们所注意到的,完全不会改变的通用样式将属于第一个部分,而每个样式模式的特定样式将进入其对应的部分。

解释

.ClassName 被称为类选择器。通过使用类名(不带点)作为任何 HTML 元素的 class 属性的值,我们实际上是将该类中的样式应用于该元素。

现在,如果我们这样做,会发生什么?

.ClassName1 .ClassName2

例如:

.Mode1 .MainTitle

像这样的选择器中包含的样式将应用于任何类名为“MainTitle”并且同时**位于**类名为“Mode1”的另一个元素**内部**的元素。这引出了一个问题:“Mode1”类将应用于哪里?我们将其应用于页面中几乎最外层的元素,即 form 元素。这样,所有元素都包含在一个类为“Mode1”的 form 中,如果我们给任何这样的元素一个类“MainTitle”,那么我们就应用了“.Mode1 .MainTitle”块中的样式。

现在,如果 .Mode2 .MainTitle 包含其他样式,并且我们需要在特定时间应用它们,那么我们所需要做的就是给“form”元素一个“Mode2”的样式,而所有其他类为“MainTitle”的元素保持不变。

下一节将解释我们如何让 form 元素在正确的时间拥有适当的类值。

调味料

这就是 ASP.NET 用于尽可能自动地提供此功能的地方。我们需要让我们的页面继承自所谓的“基页”或“母版页”,我们可以在其中放置网站所有页面共有的功能。

基页或母版页通常用于比仅仅样式设置更多的用途。它们用于放置需要对所有页面可用的所有通用行为。通过组合基页(功能)和模板用户控件(外观),可以实现跨网站的统一外观(相同的页眉、左侧、右侧和页脚横幅)。讨论“基页”不是本文的重点。我们只是使用它们来为所有页面添加我们的样式逻辑。虽然可行,但不推荐,在每个需要样式功能的页面中添加相同的逻辑。因此,重点不在于基页本身,而在于它提供的内容。

首先,我们添加这个私有成员来表示我们所在的样式模式:

private string _StyleClass;
public string StyleClass
{
    get
    {
        return _StyleClass;
    }
    set
    {
        _StyleClass = value;
    }
}

然后,我们在基页中添加此方法:

private void styleForm()
{
    HtmlForm Form1 = (HtmlForm)this.FindControl("Form1");
    Form1.Attributes.Add("class", _StyleClass);
}

最后,我们在重写的 OnPrerender 方法中调用该方法:

protected override void OnPreRender(EventArgs e)
{
    base.OnPreRender (e);
    //give the Form element the appropriate style class
    styleForm();
}

解释

正如我之前提到的,翻转页面外观所需的唯一操作就是更改应用于 form 元素的类。在这里,我们通过设置我们想要更改样式的页面中 StyleClass 属性的值来动态地做到这一点,如下所示:

StyleClass = ddlMode.SelectedValue;

其中 ddlMode.SelectedValue 是一个 DropDownList,其中包含我们想要切换的多种样式模式。

<asp:DropDownList id=ddlMode AutoPostBack="True" Runat="server">
    <asp:ListItem Selected="True" Value="Mode1">Mode1</asp:ListItem>
    <asp:ListItem Value="Mode2">Mode2</asp:ListItem>
</asp:DropDownList>

styleForm 方法获取对名为(名称不得更改)“Form1”的 form 的引用。然后,一个类被添加到 form 元素中,该类的名称将是我们使用 StyleClass 属性在页面中设置的值。

styleForm 方法在 OnPrerender 方法中调用,以确保在 StyleClass 属性被使用之前设置好。

就这样。所有这些所需要的只是设置一个属性,然后我们样式表中的样式就会被应用。

潜在用途

这项技术有许多用途。在此,我列举几项:

  1. 为您的网站提供用户可选择的主题。
  2. 季节性样式。
  3. 也许最重要的应用之一(我使用的一种)将是多语言样式,我们需要为每种支持的语言设置一种样式。

结论

稍加观察,您可能会注意到这种使用 CSS 的方式强调了 CSS 的一种(或多或少)面向对象的视图。这体现在使用一个包含通用样式的通用类,然后如果术语可用的话,在“子类”中指定样式。在我们的示例中,主类将是 .Mode1,而“子类”将是“.Mode1 MainTitle”和“.Mode1 .SubTitle”。归根结底,在我看来,这比将所有样式都放在代码中要好。

喜欢?给它投票...

参考文献

有关 CSS 的更多信息,请尝试 W3SchoolsW3C,或查看 这篇文章以获得更深入的见解。

关于基页,请使用 Google;如果您在此遇到问题,请告诉我,我仍在考虑撰写一篇关于该主题的文章。

© . All rights reserved.