今天想做些练习,做什么呢?还是练习一下动态变更样式吧。此博文在应用用户控件,接口,事件等知识,可以让你学习到编程的思想,如果是你来写,你是从哪一步开始,或是有另外种写法,都可达到相同的目标,绝招同途异路。

准备三种样式,在站点中创建一个目录"StyleSheet"用来存储样式文件,样式文件名分别为StyleSheet.css,SS_css1.css和SS_css2.css。

动态变更网页样式_stylesheet动态变更网页样式_CSS_02StyleSheet.css
body
{    
   
}

.textbox {
    border:solid 1px #000;
}

 

动态变更网页样式_stylesheet动态变更网页样式_CSS_02SS_css1.css
body
{    
   
}

.textbox {   
    border:solid 1px #0094ff;   
}

 

动态变更网页样式_stylesheet动态变更网页样式_CSS_02SS_css2.css
body
{    
   
}

.textbox {
   border:solid 1px #f00;   
}


创建一个aspx网页,创建时,把Place code in separate file选项选中,将代码放在单独的文件。
拉StyleSheet.css样式文件入aspx网页中,为样式链接添加ID和runat属性

<link id="StyleSheet1" runat="server" href="StyleSheet/StyleSheet.css" rel="stylesheet" />


还要往网页拉一个asp:TextBox控件,添加CssClass="textbox"属性。

<asp:TextBox ID="TextBox1" runat="server" CssClass="textbox"></asp:TextBox>


完整aspx如下:
动态变更网页样式_Interface_07

 

现在需要做的是,网页运行时,能够变更它的样式:

 protected void Page_Load(object sender, EventArgs e)
    {
        this.StyleSheet1.Attributes["href"] = "~/StyleSheet/" + "StyleSheet.css";   //变更样式名称
    }


动画演示:
 动态变更网页样式_Interface_08

 

看完演示动画,教程也算完了,但Insus.NET却要疯了,不可能每变更一次,去打开代码来修改一次,这是最糟糕的做法。
怎样做呢?Insus.NET做到的在网页放置各种样式,用户点选就是了。根据例子,做好三张图片,放在站点的Img目录之下。

 动态变更网页样式_CommandArgument_09

在.aspx网页显示此三张图片为图片铵钮:

 <asp:ImageButton ID="ImageButton1" runat="server" ImageAlign="AbsMiddle" ImageUrl="~/Img/000.png" OnClick="ImageButton1_Click" />
 <asp:ImageButton ID="ImageButton2" runat="server" ImageAlign="AbsMiddle" ImageUrl="~/Img/0094ff.png" OnClick="ImageButton2_Click" />
 <asp:ImageButton ID="ImageButton3" runat="server" ImageAlign="AbsMiddle" ImageUrl="~/Img/f00.png" OnClick="ImageButton3_Click" /><br />


在.cs分别好各自的OnClick事件,关Comment out Page_Load事件内的代码:

动态变更网页样式_stylesheet动态变更网页样式_CSS_02View Code
 protected void Page_Load(object sender, EventArgs e)
    {
        //this.StyleSheet1.Attributes["href"] = "~/StyleSheet/" + "StyleSheet.css";   //变更样式名称
    }
    protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
    {
        this.StyleSheet1.Attributes["href"] = "~/StyleSheet/" + "StyleSheet.css";
    }
    protected void ImageButton2_Click(object sender, ImageClickEventArgs e)
    {
        this.StyleSheet1.Attributes["href"] = "~/StyleSheet/" + "SS_css1.css";
    }
    protected void ImageButton3_Click(object sender, ImageClickEventArgs e)
    {
        this.StyleSheet1.Attributes["href"] = "~/StyleSheet/" + "SS_css2.css";
    }


看看改变后的效果:
动态变更网页样式_stylesheet_12

 

 写到这里,Insus.NET又发现,每个事件中的代码冗余,因此Insus.NET把它抽取为一个方法,然后每个事件中直接执行这个方法,并传入相应的参数即可:

动态变更网页样式_stylesheet动态变更网页样式_CSS_02View Code
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
    {
        DynamicallySetStyleSheet("StyleSheet.css");
    }

    protected void ImageButton2_Click(object sender, ImageClickEventArgs e)
    {
        DynamicallySetStyleSheet("SS_css1.css");
    }

    protected void ImageButton3_Click(object sender, ImageClickEventArgs e)
    {
        DynamicallySetStyleSheet("SS_css2.css");
    }

    //改善代码冗余,抽取为一个方法。
    private void DynamicallySetStyleSheet(string cssName)
    {
        this.StyleSheet1.Attributes["href"] = "~/StyleSheet/" + cssName;
    }

 

 呵呵,程序一步一步完善,可以想一下,日后样式需要增多,每增一次,又得来打开这个网页,添加图片按钮,添加事件...
是否可以不做到“改变一点而动全身”呢?程序是可以尝试一下的。

 Insus.NET想到的是,把这部常变的代码,移至一个用户控件(ascx)内,有什么奕化,只更改此ascx即可。以下面在站点创建一个用户控件DynamicallySetupStyle.ascx:
然后把把三个按钮的html 剪下,粘帖于用户控件。

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="DynamicallySetupStyle.ascx.cs" Inherits="DynamicallySetupStyle" %>
<asp:ImageButton ID="ImageButton1" runat="server" ImageAlign="AbsMiddle" ImageUrl="~/Img/000.png" OnClick="ImageButton1_Click" />
<asp:ImageButton ID="ImageButton2" runat="server" ImageAlign="AbsMiddle" ImageUrl="~/Img/0094ff.png" OnClick="ImageButton2_Click" />
<asp:ImageButton ID="ImageButton3" runat="server" ImageAlign="AbsMiddle" ImageUrl="~/Img/f00.png" OnClick="ImageButton3_Click" /><br />


三个OnClick事件也照搬:

动态变更网页样式_stylesheet动态变更网页样式_CSS_02View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class DynamicallySetupStyle : System.Web.UI.UserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
    {
        DynamicallySetStyleSheet("StyleSheet.css");
    }

    protected void ImageButton2_Click(object sender, ImageClickEventArgs e)
    {
        DynamicallySetStyleSheet("SS_css1.css");
    }

    protected void ImageButton3_Click(object sender, ImageClickEventArgs e)
    {
        DynamicallySetStyleSheet("SS_css2.css");
    }   
}


此时的程序,在ascx的每个OnClick事件中,会找不到DynamicallySetStyleSheet(string xxx)方法,因为Insus.NET没有搬过去。怎样解决这个跨页访问方法的问题呢?不用担心,很简单的。

可以写一个接口,接口内的方法,就是与Page的private的方法一样:

动态变更网页样式_stylesheet动态变更网页样式_CSS_02ISetValable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// Summary description for ISetValable
/// </summary>
namespace Insus.NET
{
    public interface ISetValable
    {
       void DynamicallySetStyleSheet(string cssName);
    }
}


然后在.aspx.cs件实作这个接口即可,实作之后,原先的Private已经变为Public修饰符了,参考下图高亮位置。
动态变更网页样式_stylesheet_19

 

下面是用户控件的代码,参考高亮的位置:
动态变更网页样式_CommandArgument_20

 

 最后是用户控件拉至.aspx网页中:
动态变更网页样式_stylesheet_21

 
经过这样一改,有样式添加的话,我们只需要更改此用户控件即可。不必去动那个.aspx网页了。
写到此, 如果以添加多几个样式,供用户选择,需要添加一个ImageButton,还要写事件,这样的话,用户控件的事件也许会越来越多。Insus.NET又想到要重构这个用户控件。看看怎样才不用动很多地方。

在DynamicallySetupStyle.ascx网页,拿掉所有ImageButton代码,用PlaceHolder控件来替代。

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="DynamicallySetupStyle.ascx.cs" Inherits="DynamicallySetupStyle" %>
<%--<asp:ImageButton ID="ImageButton1" runat="server" ImageAlign="AbsMiddle" ImageUrl="~/Img/000.png" OnClick="ImageButton1_Click" />&nbsp;
<asp:ImageButton ID="ImageButton2" runat="server" ImageAlign="AbsMiddle" ImageUrl="~/Img/0094ff.png" OnClick="ImageButton2_Click" />
<asp:ImageButton ID="ImageButton3" runat="server" ImageAlign="AbsMiddle" ImageUrl="~/Img/f00.png" OnClick="ImageButton3_Click" />--%>

<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder><br />


在DynamicallySetupStyle.ascx.cs中,拿掉所有ImageButton事件:

  //protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
    //{
    //    DynamicallySetStyleSheet("StyleSheet.css");
    //}

    //protected void ImageButton2_Click(object sender, ImageClickEventArgs e)
    //{
    //    DynamicallySetStyleSheet("SS_css1.css");
    //}

    //protected void ImageButton3_Click(object sender, ImageClickEventArgs e)
    //{
    //    DynamicallySetStyleSheet("SS_css2.css");
    //}


取而代之的是:
动态变更网页样式_Interface_22

 

经过此一改,以后添加样式,或减少样式,只改上图高亮位置两行代码。