今天想做些練習,做什么呢?還是練習一下動態變更樣式吧。此博文在應用用戶控件,接口,事件等知識,可以讓你學習到編程的思想,如果是你來寫,你是從哪一步開始,或是有另外種寫法,都可達到相同的目標,絕招同途異路。
准備三種樣式,在站點中創建一個目錄"StyleSheet"用來存儲樣式文件,樣式文件名分別為StyleSheet.css,SS_css1.css和SS_css2.css。

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

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

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>
現在需要做的是,網頁運行時,能夠變更它的樣式:
protected void Page_Load(object sender, EventArgs e) { this.StyleSheet1.Attributes["href"] = "~/StyleSheet/" + "StyleSheet.css"; //變更樣式名稱 }
看完演示動畫,教程也算完了,但Insus.NET卻要瘋了,不可能每變更一次,去打開代碼來修改一次,這是最糟糕的做法。
怎樣做呢?Insus.NET做到的在網頁放置各種樣式,用戶點選就是了。根據例子,做好三張圖片,放在站點的Img目錄之下。
在.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事件內的代碼:

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"; }
看看改變后的效果:
寫到這里,Insus.NET又發現,每個事件中的代碼冗余,因此Insus.NET把它抽取為一個方法,然后每個事件中直接執行這個方法,並傳入相應的參數即可:

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事件也照搬:

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的方法一樣:

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修飾符了,參考下圖高亮位置。
經過這樣一改,有樣式添加的話,我們只需要更改此用戶控件即可。不必去動那個.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" /> <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"); //}
經過此一改,以后添加樣式,或減少樣式,只改上圖高亮位置兩行代碼。