設定檔、佈景主題與 Web 組件

Microsoft提供

ASP.NET 2.0 中的組態和檢測有重大變更。 新的 ASP.NET 組態 API 允許以程式設計方式進行組態變更。 此外,有許多新的組態設定都允許新的組態和檢測。

ASP.NET 2.0 代表個人化網站領域的大幅改善。 除了我們已涵蓋的成員資格功能之外,ASP.NET 設定檔、主題和網頁元件大幅增強網站中的個人化。

ASP.NET 設定檔

ASP.NET 設定檔類似于會話。 差異在於設定檔是持續性的,而當瀏覽器關閉時,會話就會遺失。 會話和設定檔之間的另一大差異是設定檔是強型別的,因此在開發過程中提供 IntelliSense。

設定檔定義于電腦群組態檔或應用程式的web.config檔案中。 (您無法在子資料夾中定義設定檔,web.config file.) 下列程式碼會定義設定檔來儲存網站訪客的名字和姓氏。

<profile>
    <properties>
        <add name="FirstName" />
        <add name="LastName" />
    </properties>
</profile>

配置檔案屬性的預設資料類型為 System.String。 在上述範例中,未指定資料類型。 因此,FirstName 和 LastName 屬性都是 String 類型。 如先前所述,配置檔案屬性是強型別。 下列程式碼會針對類型為 Int32 的年齡新增屬性。

<profile>
    <properties>
        <add name="FirstName" />
        <add name="LastName" />
        <add name="Age" type="Int32"/>
    </properties>
</profile>

設定檔通常會與 ASP.NET Forms 驗證搭配使用。 搭配表單驗證使用時,每個使用者都有與其使用者識別碼相關聯的個別設定檔。 不過,您也可以使用組態檔中的 anonymousIdentification > 元素以及allowAnonymous屬性,允許在匿名應用程式中使用 < 設定檔,如下所示:

<anonymousIdentification enabled="true" />
<profile>
    <properties>
        <add name="FirstName" allowAnonymous="true" />
        <add name="LastName" allowAnonymous="true" />
    </properties>
</profile>

當匿名使用者流覽網站時,ASP.NET 為使用者建立 ProfileCommon 的實例。 此設定檔會使用儲存在瀏覽器上的 Cookie 中的唯一識別碼,將使用者識別為唯一訪客。 如此一來,您就可以為匿名流覽的使用者儲存設定檔資訊。

設定檔群組

可以群組設定檔的屬性。 藉由將屬性分組,即可模擬特定應用程式的多個設定檔。

下列組態會設定兩個群組的 FirstName 和 LastName 屬性;購買者和潛在客戶。

<profile>
    <properties>
        <group name="Buyers">
            <add name="FirstName" />
            <add name="Lastname" />
            <add name="NumberOfPurchases" type="Int32" />
        </group>
        <group name="Prospects">
            <add name="FirstName" />
            <add name="Lastname" />
        </group>
    </properties>
</profile>

然後,就可以在特定群組上設定屬性,如下所示:

Profile.Buyers.NumberOfPurchases += 1;

儲存複雜物件

到目前為止,我們涵蓋的範例已將簡單的資料類型儲存在設定檔中。 您也可以使用 serializeAs 屬性指定序列化方法,將複雜的資料類型儲存在設定檔中,如下所示:

<add name="PurchaseInvoice"
     type="PurchaseInvoice"
     serializeAs="Binary"
/>

在此情況下,此類型為 PurchaseInvoice。 PurchaseInvoice 類別必須標示為可序列化,而且可以包含任意數目的屬性。 例如,如果 PurchaseInvoice 有名為 NumItemsPurchased的屬性,您可以在程式碼中參考該屬性,如下所示:

Profile.PurchaseInvoice.NumItemsPurchased

設定檔繼承

可以建立設定檔以用於多個應用程式。 藉由建立衍生自 ProfileBase 的設定檔類別,您可以使用 繼承 屬性在數個應用程式中重複使用設定檔,如下所示:

<profile inherits="PurchasingProfile" />

在此情況下, 購買Profile 類別看起來會像這樣:

using System;
using System.Web.Profile;
public class PurchasingProfile : ProfileBase {
    private string _ProductName;
    private Int32 _ProductID;
    public string ProductName {
        get { return _ProductName; }
        set { _ProductName = value; }
    }
    public Int32 ProductID {
        get { return _ProductID; }
        set { _ProductID = value; }
    }
}

設定檔提供者

ASP.NET 設定檔使用提供者模型。 預設提供者會使用 SqlProfileProvider 提供者,將資訊儲存在 Web 應用程式的 App_Data 資料夾中SQL Server Express資料庫中。 如果資料庫不存在,當設定檔嘗試儲存資訊時,ASP.NET 會自動建立資料庫。

不過,在某些情況下,您可能想要開發自己的設定檔提供者。 ASP.NET 設定檔功能可讓您輕鬆地使用不同的提供者。

您可以在下列情況下建立自訂設定檔提供者:

  • 您必須將設定檔資訊儲存在資料來源中,例如在 FoxPro 資料庫或 Oracle 資料庫中,而設定檔提供者隨附于.NET Framework不支援。
  • 您必須使用與.NET Framework隨附提供者所使用的資料庫架構不同的資料庫架構來管理設定檔資訊。 常見的範例是您想要將設定檔資訊與現有SQL Server資料庫中的使用者資料整合。

必要類別

若要實作設定檔提供者,您可以建立繼承 System.Web.Profile.ProfileProvider 抽象類別的類別。 ProfileProvider抽象類別接著會繼承 System.Configuration.SettingsProvider 抽象類別,其繼承 System.Configuration.Provider.ProviderBase 抽象類別。 由於這個繼承鏈結,除了 ProfileProvider 類別的必要成員之外,您還必須實作 SettingsProviderProviderBase 類別的必要成員。

下表描述您必須從 ProviderBaseSettingsProviderProfileProvider 抽象類別實作的屬性和方法。

ProviderBase 成員

成員 描述
Initialize 方法 接受提供者實例的名稱和組態設定的 NameValueCollection。 用來設定提供者實例的選項和屬性值,包括電腦群組態或Web.config檔案中指定的實作特定值和選項。

SettingsProvider 成員

成員 描述
ApplicationName 屬性 每個設定檔所儲存的應用程式名稱。 設定檔提供者會使用應用程式名稱來個別儲存每個應用程式的設定檔資訊。 這可讓多個 ASP.NET 應用程式在不同的應用程式中建立相同的使用者名稱時,使用相同的資料來源,而不會發生衝突。 或者,多個 ASP.NET 應用程式可以藉由指定相同的應用程式名稱來共用設定檔資料來源。
GetPropertyValues 方法 接受 SettingsCoNtext 和 SettingsPropertyCollection 物件的輸入。 SettingsCoNtext提供使用者的相關資訊。 您可以使用資訊作為主鍵來擷取使用者的配置檔案屬性資訊。 使用 SettingsCoNtext 物件來取得使用者名稱,以及使用者是否已驗證或匿名。 SettingsPropertyCollection 包含 SettingsProperty物件的集合。 每個 SettingsProperty 物件都會提供屬性的名稱和類型,以及屬性的預設值,以及屬性是否為唯讀等其他資訊。 GetPropertyValues方法會根據提供做為輸入的SettingsProperty 物件,以 SettingsPropertyValue物件填入 SettingsPropertyValueCollection。 指定之使用者的資料來源值會指派給每個 SettingsPropertyValue 物件的 PropertyValue 屬性,並傳回整個集合。 呼叫 方法也會將指定使用者設定檔的 LastActivityDate 值更新為目前的日期和時間。
SetPropertyValues 方法 接受 SettingsCoNtextSettingsPropertyValueCollection 物件的輸入。 SettingsCoNtext提供使用者的相關資訊。 您可以使用資訊作為主鍵來擷取使用者的配置檔案屬性資訊。 使用 SettingsCoNtext 物件來取得使用者名稱,以及使用者是否已驗證或匿名。 SettingsPropertyValueCollection包含SettingsPropertyValue物件的集合。 每個 SettingsPropertyValue 物件都會提供屬性的名稱、類型和值,以及屬性的預設值,以及屬性是否為唯讀等其他資訊。 SetPropertyValues方法會更新指定使用者資料來源中的配置檔案屬性值。 呼叫 方法也會將指定使用者設定檔的 LastActivityDate 和 LastUpdatedDate 值更新為目前的日期和時間。

ProfileProvider 成員

成員 描述
DeleteProfiles 方法 接受輸入使用者名稱的字串陣列,並從資料來源中刪除指定名稱的所有設定檔資訊和屬性值,其中應用程式名稱符合 ApplicationName 屬性值。 如果您的資料來源支援交易,建議您在交易中包含所有刪除作業,而且復原交易,並在任何刪除作業失敗時擲回例外狀況。
DeleteProfiles 方法 接受 ProfileInfo 物件的輸入,並從資料來源中刪除每個設定檔的設定檔資訊和屬性值,其中應用程式名稱符合 ApplicationName 屬性值。 如果您的資料來源支援交易,建議您在交易中包含所有刪除作業,並回復交易,並在任何刪除作業失敗時擲回例外狀況。
DeleteInactiveProfiles 方法 接受 ProfileAuthenticationOption 值和 DateTime 物件,並從資料來源中刪除最後一個活動日期小於或等於指定日期和時間以及應用程式名稱符合 ApplicationName 屬性值的所有設定檔資訊和屬性值。 ProfileAuthenticationOption參數會指定只匿名設定檔、只驗證的設定檔,還是要刪除所有設定檔。 如果您的資料來源支援交易,建議您在交易中包含所有刪除作業,並回復交易,並在任何刪除作業失敗時擲回例外狀況。
GetAllProfiles 方法 接受 ProfileAuthenticationOption 值的輸入、指定頁面索引的整數、指定頁面大小的整數,以及將設定為設定檔總數的整數參考。 會傳回 ProfileInfoCollection,其中包含資料來源中應用程式名稱符合ApplicationName屬性值之所有設定檔的ProfileInfo物件。 ProfileAuthenticationOption參數會指定只傳回匿名設定檔、只驗證的設定檔或所有設定檔。 GetAllProfiles方法傳回的結果會受到頁面索引和頁面大小值的限制。 頁面大小值會指定要在ProfileInfoCollection中傳回的ProfileInfo物件數目上限。 頁面索引值會指定要傳回的結果頁面,其中 1 會識別第一頁。 總記錄的參數是 out 參數 (您可以在 Visual Basic 中使用 ByRef) ,該參數設定為設定檔總數。 例如,如果資料存放區包含應用程式的 13 個設定檔,且頁面索引值為 2 且頁面大小為 5,則傳回的 ProfileInfoCollection 會包含第六到第十個設定檔。 方法傳回時,總記錄值會設定為 13。
GetAllInactiveProfiles 方法 接受 ProfileAuthenticationOption 值、 DateTime 物件、指定頁面索引的整數、指定頁面大小的整數,以及設定為設定檔總數之整數的參考。 會傳回ProfileInfoCollection,其中包含資料來源中最後一個活動日期小於或等於指定DateTime且應用程式名稱符合ApplicationName屬性值之所有設定檔的ProfileInfo物件。 ProfileAuthenticationOption參數會指定只傳回匿名設定檔、只驗證的設定檔或所有設定檔。 GetAllInactiveProfiles方法傳回的結果會受到頁面索引和頁面大小值的限制。 頁面大小值會指定要在ProfileInfoCollection中傳回的ProfileInfo物件數目上限。 頁面索引值會指定要傳回的結果頁面,其中 1 會識別第一頁。 總記錄的參數是 out 參數 (您可以在 Visual Basic 中使用 ByRef) ,該參數設定為設定檔總數。 例如,如果資料存放區包含應用程式的 13 個設定檔,且頁面索引值為 2 且頁面大小為 5,則傳回的 ProfileInfoCollection 會包含第六到第十個設定檔。 方法傳回時,總記錄值會設定為 13。
FindProfilesByUserName 方法 接受 做為輸入 ProfileAuthenticationOption 值、包含使用者名稱的字串、指定頁面索引的整數、指定頁面大小的整數,以及將設定為設定檔總數的整數參考。 會傳回 ProfileInfoCollection ,其中包含資料來源中所有設定檔的 ProfileInfo 物件,其中使用者名稱符合指定的使用者名稱,以及應用程式名稱符合 ApplicationName 屬性值的位置。 ProfileAuthenticationOption參數會指定只傳回匿名設定檔、只驗證的設定檔或所有設定檔。 如果您的資料來源支援其他搜尋功能,例如萬用字元,您可以為使用者名稱提供更廣泛的搜尋功能。 FindProfilesByUserName方法傳回的結果會受到頁面索引和頁面大小值的限制。 頁面大小值會指定要在ProfileInfoCollection中傳回的ProfileInfo物件數目上限。 頁面索引值會指定要傳回的結果頁面,其中 1 會識別第一頁。 總記錄的參數是 out 參數 (您可以在 Visual Basic 中使用 ByRef) ,該參數設定為設定檔總數。 例如,如果資料存放區包含應用程式的 13 個設定檔,且頁面索引值為 2 且頁面大小為 5,則傳回的 ProfileInfoCollection 會包含第六到第十個設定檔。 方法傳回時,總記錄值會設定為 13。
FindInactiveProfilesByUserName 方法 接受 做為輸入 ProfileAuthenticationOption 值、包含使用者名稱的字串、 DateTime 物件、指定頁面索引的整數、指定頁面大小的整數,以及設定為設定檔總數的整數參考。 會傳回 ProfileInfoCollection ,其中包含資料來源中所有設定檔的 ProfileInfo 物件,其中使用者名稱符合指定的使用者名稱、最後一個活動日期小於或等於指定的 DateTime,以及應用程式名稱符合 ApplicationName 屬性值的位置。 ProfileAuthenticationOption參數會指定只傳回匿名設定檔、只驗證的設定檔或所有設定檔。 如果您的資料來源支援其他搜尋功能,例如萬用字元,您可以為使用者名稱提供更廣泛的搜尋功能。 FindInactiveProfilesByUserName方法傳回的結果會受到頁面索引和頁面大小值的限制。 頁面大小值會指定要在ProfileInfoCollection中傳回的ProfileInfo物件數目上限。 頁面索引值會指定要傳回的結果頁面,其中 1 會識別第一頁。 總記錄的參數是 out 參數 (您可以在 Visual Basic 中使用 ByRef) ,該參數設定為設定檔總數。 例如,如果資料存放區包含應用程式的 13 個設定檔,且頁面索引值為 2 且頁面大小為 5,則傳回的 ProfileInfoCollection 會包含第六到第十個設定檔。 方法傳回時,總記錄值會設定為 13。
GetNumberOfInActiveProfiles 方法 接受 做為輸入 ProfileAuthenticationOption 值和 DateTime 物件,並傳回資料來源中最後一個活動日期小於或等於指定 DateTime 以及應用程式名稱符合 ApplicationName 屬性值的所有設定檔計數。 ProfileAuthenticationOption參數會指定是否只有匿名設定檔、僅驗證的設定檔,或要計算所有設定檔。

ApplicationName

由於設定檔提供者會個別儲存每個應用程式的設定檔資訊,因此您必須確定您的資料架構包含應用程式名稱,而且查詢和更新也包含應用程式名稱。 例如,下列命令可用來根據使用者名稱以及設定檔是否為匿名,從資料庫擷取屬性值,並確保 查詢中包含 ApplicationName 值。

SELECT Property
FROM PropertyTable
WHERE Username = 'user1'
AND IsAnonymous = False
AND ApplicationName = 'MyApplication'

ASP.NET 主題

什麼是 ASP.NET 2.0 主題?

Web 應用程式的其中一個最重要的層面是整個網站的一致外觀和風格。 ASP.NET 1.x 開發人員通常會使用級聯樣式表 (CSS) 來實作一致的外觀與風格。 ASP.NET 2.0 主題大幅改善 CSS,因為它們可讓 ASP.NET 開發人員定義 ASP.NET 伺服器控制項和 HTML 元素的外觀。 ASP.NET 主題可以套用至個別控制項、特定網頁或整個 Web 應用程式。 主題會使用 CSS 檔案、選擇性面板檔案,以及視需要影像的選擇性 Images 目錄的組合。 面板檔案會控制 ASP.NET 伺服器控制項的視覺外觀。

主題儲存在哪裡?

主題儲存的位置會根據其範圍而有所不同。 可套用至任何應用程式的主題會儲存在下列資料夾中:

C:\WINDOWS\Microsoft.NET\Framework\v2.x.xxxxx\ASP.NETClientFiles\Themes\<Theme_Name>

特定應用程式特有的主題會儲存在 App\_Themes\<Theme\_Name> 網站的根目錄中。

注意

面板檔案應該只修改影響外觀的伺服器控制項屬性。

全域主題是一個主題,可以套用至在 Web 服務器上執行的任何應用程式或網站。 這些主題預設會儲存在 ASP 中。v2.x.xxxxx 目錄中的 NETClientfiles\Themes 目錄。 或者,您可以將主題檔案移至網站根目錄中的 aspnet_client/system_web/[version]/Themes/[theme_name] 資料夾中。

應用程式特定主題只能套用至檔案所在的應用程式。 這些檔案會儲存在 App\_Themes/<theme\_name> 網站的根目錄中。

主題的元件

主題是由一或多個 CSS 檔案、選擇性面板檔案和選用的 Images 資料夾所組成。 CSS 檔案可以是您想要 (的任何名稱,亦即 default.css 或 theme.css 等) ,而且必須位於主題資料夾的根目錄中。 CSS 檔案可用來定義特定選取器的一般 CSS 類別和屬性。 若要將其中一個 CSS 類別套用至頁面元素,則會使用 CSSClass 屬性。

面板檔案是 XML 檔案,其中包含 ASP.NET 伺服器控制項的屬性定義。 下列程式碼是範例面板檔案。

<asp:TextBox runat="server"
    BackColor="#FFC080"
    BorderColor="Black"
    BorderStyle="Solid"
    BorderWidth="1px"
    Font-Names="Tahoma, Verdana, Arial"
    Font-Size="Smaller" />

<asp:Button runat="server"
    BackColor="#C04000"
    BorderColor="Maroon"
    BorderStyle="Solid"
    BorderWidth="2px"
    Font-Names="Tahoma,Verdana,Arial"
    Font-Size="Smaller"
    ForeColor="#FFFFC0" />

圖 1 顯示未套用主題的小型 ASP.NET 網頁。 圖 2 顯示套用主題的相同檔案。 背景色彩和文字色彩是透過 CSS 檔案來設定。 按鈕和文字方塊的外觀是使用上面所列的面板檔案來設定。

無主題

圖 1:沒有主題

套用的主題

圖 2:套用的主題

上述面板檔案會定義所有 TextBox 控制項和 Button 控制項的預設面板。 這表示在頁面上插入的每個 TextBox 控制項和按鈕控制項都會採用這個外觀。 您也可以使用 控制項的 SkinID 屬性,定義可套用至這些控制項的特定實例的面板。

下列程式碼會定義按鈕控制項的面板。 只有具有goButton之 SkinID屬性的 Button 控制項會採用外觀。

<asp:Button runat="server"
    BackColor="#C04000"
    BorderColor="Maroon"
    BorderStyle="Solid"
    BorderWidth="2px"
    Font-Names="Tahoma,Verdana,Arial"
    Font-Size="Smaller"
    ForeColor="#FFFFC0"
    Text=go
    SkinID=goButton
    Width="95px" />

每個伺服器控制項類型只能有一個預設面板。 如果您需要其他面板,您應該使用 SkinID 屬性。

將主題套用至頁面

您可以使用下列任何一種方法來套用主題:

  • 在 < web.config 檔案的 pages > 元素中
  • @Page在頁面的 指示詞中
  • 以程式設計方式

在組態檔中套用主題

若要在應用程式組態檔中套用主題,請使用下列語法:

<system.web>
    <pages theme="CoolTheme" />
    ...
</system.web>

此處指定的主題名稱必須符合主題資料夾的名稱。 此資料夾可以存在於本課程稍早所述的任一位置中。 如果您嘗試套用不存在的主題,就會發生設定錯誤。

在 Page 指示詞中套用主題

您也可以在 @ Page 指示詞中套用主題。 這個方法可讓您針對特定頁面使用主題。

若要在 @Page 指示詞中套用主題,請使用下列語法:

<%@ Page Language="C#" Theme=CoolTheme CodeFile="Default.aspx.cs" ... %>

同樣地,此處指定的主題必須符合先前所述的主題資料夾。 如果您嘗試套用不存在的主題,就會發生建置失敗。 Visual Studio 也會反白顯示 屬性,並通知您沒有這類主題存在。

以程式設計方式套用主題

若要以程式設計方式套用主題,您必須在Page_PreInit方法中指定頁面的Theme屬性。

若要以程式設計方式套用主題,請使用下列語法:

Page.Theme = CoolTheme;

由於頁面生命週期,必須在 PreInit 方法中套用主題。 如果您在該點之後套用它,則執行時間已套用頁面主題,且該時間點的變更在生命週期中太晚。 如果您套用不存在的主題, 就會發生 HttpException 。 以程式設計方式套用主題時,如果有任何伺服器控制項指定了 SkinID 屬性,就會發生建置警告。 此警告旨在通知您不會以宣告方式套用任何主題,而且可以忽略。

練習 1:套用主題

在此練習中,您會將 ASP.NET 主題套用至網站。

重要

如果您使用 Microsoft Word 在面板檔案中輸入資訊,請確定您不會以智慧引號取代一般引號。 智慧引號會導致面板檔案發生問題。

  1. 建立新的 ASP.NET 網站。

  2. 以滑鼠右鍵按一下方案總管中的專案,然後選擇 [新增專案]。

  3. 從檔案清單中選擇 [Web 組態檔],然後按一下 [新增]。

  4. 以滑鼠右鍵按一下方案總管中的專案,然後選擇 [新增專案]。

  5. 選擇 [面板檔案],然後按一下 [新增]。

  6. 當系統詢問您是否要將檔案放在App_Themes資料夾內時,請按一下 [是]。

  7. 以滑鼠右鍵按一下 方案總管 中App_Themes資料夾內的 SkinFile 資料夾,然後選擇 [新增專案]。

  8. 從檔案清單中選擇 [樣式表單],然後按一下 [新增]。 您現在有實作新主題所需的所有檔案。 不過,Visual Studio 已將您的主題資料夾命名為 SkinFile。 以滑鼠右鍵按一下該資料夾,並將名稱變更為 CoolTheme。

  9. 開啟 SkinFile.skin 檔案,並在檔案結尾處新增下列程式碼:

    <asp:TextBox runat="server"
        BackColor="#FFC080"
        BorderColor="Black"
        BorderStyle="Solid"
        BorderWidth="1px"
        Font-Names="Tahoma, Verdana, Arial"
        Font-Size="Smaller"
    />
    
    <asp:Button runat="server"
        BackColor="#C04000"
        BorderColor="Maroon"
        BorderStyle="Solid"
        BorderWidth="2px"
        Font-Names="Tahoma,Verdana,Arial"
        Font-Size="Smaller"
        ForeColor="#FFFFC0"
    />
    
    <asp:Button runat="server"
        BackColor="#C04000"
        BorderColor="Maroon"
        BorderStyle="Solid"
        BorderWidth="2px"
        Font-Names="Tahoma,Verdana,Arial"
        Font-Size="Smaller"
        ForeColor="#FFFFC0"
        Text="go"
        SkinID="goButton"
        Width="95px"
    />
    
  10. 儲存 SkinFile.skin 檔案。

  11. 開啟 StyleSheet.css。

  12. 以下列內容取代其中的所有文字:

    body {
        background-color: #FFDEAD;
    }
    
  13. 儲存 StyleSheet.css 檔案。

  14. 開啟 Default.aspx 頁面。

  15. 新增 TextBox 控制項和 Button 控制項。

  16. 儲存網頁。 現在流覽 Default.aspx 頁面。 它應該會顯示為一般 Web 表單。

  17. 開啟web.config檔案。

  18. 在開頭 <system.web> 標記正下方新增下列內容:

    <pages theme="CoolTheme" />
    
  19. 儲存 web.config 檔案。 現在流覽 Default.aspx 頁面。 它應該會顯示並套用主題。

  20. 如果尚未開啟,請在 Visual Studio 中開啟 Default.aspx 頁面。

  21. 選取 [按鈕]。

  22. SkinID 屬性變更為 goButton。 請注意,Visual Studio 會為按鈕控制項提供具有有效 SkinID 值的下拉式清單。

  23. 儲存網頁。 現在再次預覽瀏覽器中的頁面。 按鈕現在應該會說出「移至」,而且外觀應該更寬。

使用 SkinID 屬性,您可以輕鬆地為特定類型伺服器控制項的不同實例設定不同的面板。

StyleSheetTheme 屬性

到目前為止,我們只討論過如何使用 Theme 屬性來套用主題。 使用 Theme 屬性時,面板檔案會覆寫伺服器控制項的任何宣告式設定。 例如,在練習 1 中,您為按鈕控制項指定了 「goButton」 的 SkinID,並將按鈕的文字變更為 「go」。 您可能已經注意到設計工具中 Button 的 Text 屬性已設定為 「Button」,但主題過度設定。 主題一律會覆寫設計工具中的任何屬性設定。

如果您想要能夠使用設計工具中指定的屬性覆寫主題外觀檔案中定義的屬性,您可以使用 StyleSheetTheme 屬性,而不是 Theme 屬性。 StyleSheetTheme 屬性與 Theme 屬性相同,不同之處在于它不會覆寫 Theme 屬性之類的所有明確屬性設定。

若要查看此動作,請在練習 1 中開啟專案中的web.config檔案,並將 <pages> 元素變更為下列專案:

<pages styleSheetTheme="CoolTheme" />

現在流覽 Default.aspx 頁面,您會看到按鈕控制項再次具有 「Button」 的 Text 屬性。 這是因為設計工具中的明確屬性設定會覆寫 goButton SkinID 所設定的 Text 屬性。

覆寫主題

在應用程式的 App_Themes 資料夾中,套用相同名稱的主題,即可覆寫全域主題。 不過,主題不會套用在真正的覆寫案例中。 如果執行時間在 App_Themes 資料夾中遇到主題檔案,則會使用這些檔案來套用主題,並忽略全域主題。

StyleSheetTheme 屬性是可覆寫的,可以在程式碼中覆寫,如下所示:

const String THEME_NAME = "CoolTheme";
public override string StyleSheetTheme {
    get { return THEME_NAME; }
    set { Page.StyleSheetTheme = THEME_NAME; }
}

Web 組件

ASP.NET 網頁元件是一組整合的控制項,可用來建立網站,讓使用者直接從瀏覽器修改網頁的內容、外觀和行為。 修改可以套用至網站上的所有使用者或個別使用者。 當使用者修改頁面和控制項時,可以儲存設定,以在未來的瀏覽器會話之間保留使用者的個人喜好設定,稱為個人化的功能。 這些 Web 元件功能表示開發人員可以讓使用者動態個人化 Web 應用程式,而不需要開發人員或系統管理員介入。

使用 Web 元件控制項集,身為開發人員的您可以讓使用者:

  • 個人化頁面內容。 使用者可以將新的網頁元件控制項新增至頁面、將它們移除、隱藏或最小化,就像一般視窗一樣。
  • 個人化版面配置。 使用者可以將網頁元件控制項拖曳至頁面上的不同區域,或變更其外觀、屬性和行為。
  • 匯出和匯入控制項。 使用者可以匯入或匯出網頁元件控制項設定,以用於其他頁面或網站、保留屬性、外觀,甚至是控制項中的資料。 這可減少終端使用者的資料輸入和設定需求。
  • 建立連線。 使用者可以建立控制項之間的連線,例如,圖表控制項可以在股票勾號控制項中顯示資料的圖形。 使用者可以個人化連線本身,也可以個人化圖表控制項如何顯示資料的外觀和詳細資料。
  • 管理和個人化網站層級設定。 授權的使用者可以設定網站層級設定、判斷誰可以存取網站或頁面、設定角色型存取控制等等。 例如,系統管理角色中的使用者可以將網頁元件控制項設定為所有使用者共用,並防止不是系統管理員的使用者個人化共用控制項。

您通常會以下列三種方式之一使用網頁元件:建立使用 Web 元件控制項的頁面、建立個別網頁元件控制項,或建立完整的可個人化 Web 應用程式,例如入口網站。

頁面開發

頁面開發人員可以使用 Microsoft Visual Studio 2005 等視覺化設計工具來建立使用網頁元件的頁面。 使用 Visual Studio 這類工具的其中一個優點是 Web 元件控制項集提供在視覺化設計工具中拖放建立和設定 Web 元件控制項的功能。 例如,您可以使用設計工具將網頁元件區域或網頁元件編輯器控制項拖曳到設計介面上,然後使用 Web 元件控制項集所提供的 UI,在設計工具中設定控制項。 這可加快 Web 元件應用程式的開發速度,並減少您必須撰寫的程式碼數量。

控制項開發

您可以使用任何現有的 ASP.NET 控制項做為 Web 元件控制項,包括標準 Web 服務器控制項、自訂伺服器控制項和使用者控制項。 如需環境的最大程式設計控制項,您也可以建立衍生自 WebPart 類別的自訂 Web 元件控制項。 針對個別的網頁元件控制項開發,您通常會建立使用者控制項,並將其作為網頁元件控制項使用,或開發自訂網頁元件控制項。

作為開發自訂網頁元件控制項的範例,您可以建立控制項來提供其他 ASP.NET 伺服器控制項所提供的任何功能,這些控制項對於封裝為可個人化的網頁元件控制項很有用:行事曆、清單、財務資訊、新聞、計算機、RTF 控制項,用於更新內容、可編輯的格線,以連線至資料庫。 動態更新其顯示或天氣和旅遊資訊的圖表。 如果您提供視覺化設計工具與控制項,則任何使用 Visual Studio 的頁面開發人員只要將控制項拖曳到 Web 元件區域,並在設計階段進行設定,而不需要撰寫其他程式碼。

個人化是網頁元件功能的基礎。 它可讓使用者修改或個人化網頁元件控制項在頁面上的版面配置、外觀和行為。 個人化設定是長期存留的:它們不只是在目前的瀏覽器會話期間保存 (,如同檢視狀態) ,也會長期儲存,讓使用者的設定也會儲存在未來的瀏覽器會話中。 網頁元件頁面預設會啟用個人化。

UI 結構元件依賴個人化,並提供所有網頁元件控制項所需的核心結構和服務。 每個網頁元件頁面上都需要一個 UI 結構元件,就是 WebPartManager 控制項。 雖然從未顯示,但此控制項具有協調頁面上所有網頁元件控制項的重要工作。 例如,它會追蹤所有個別的網頁元件控制項。 它會管理網頁元件區域 (區域,這些區域包含頁面上的網頁元件控制項) ,以及哪些控制項位於哪個區域。 它也會追蹤及控制頁面可以位於的不同顯示模式,例如流覽、連線、編輯或目錄模式,以及個人化變更適用于所有使用者或個別使用者。 最後,它會起始及追蹤 Web 元件控制項之間的連線和通訊。

第二種 UI 結構元件是區域。 區域可作為網頁元件頁面上的建構管理員。 它們包含並組織衍生自 Part 類別的控制項 (元件控制項) ,並提供在水準或垂直方向中執行模組化頁面配置的能力。 區域也會提供通用且一致的 UI 元素 (,例如頁首和頁尾樣式、標題、框線樣式、動作按鈕等) ,這些通用元素稱為控制項的 Chrome。 不同顯示模式和各種控制項會使用數種特殊類型的區域。 下列網頁元件基本控制項一節會說明不同類型的區域。

網頁元件 UI 控制項,所有衍生自 Part 類別的控制項都會組成網頁元件頁面上的主要 UI。 網頁元件控制項集具有彈性且包容性的選項,可讓您建立元件控制項。 除了建立您自己的自訂網頁元件控制項之外,您也可以使用現有的 ASP.NET 伺服器控制項、使用者控制項或自訂伺服器控制項做為網頁元件控制項。 下一節會說明最常用於建立網頁元件頁面的基本控制項。

網頁元件基本控制項

網頁元件控制項集很廣泛,但某些控制項是必要的,因為它們是 Web 元件運作的必要專案,或因為它們是網頁元件頁面上最常使用的控制項。 當您開始使用網頁元件和建立基本網頁元件頁面時,熟悉下表所述的基本網頁元件控制項會很有説明。

Web 組件控制項 描述
WebPartManager 管理頁面上的所有網頁元件控制項。 每個網頁元件頁面只需要一個 (和一個) WebPartManager 控制項。
CatalogZone 包含 CatalogPart 控制項。 使用此區域來建立網頁元件控制項的目錄,使用者可以從中選取要新增至頁面的控制項。
EditorZone 包含 EditorPart 控制項。 使用此區域可讓使用者編輯及個人化頁面上的網頁元件控制項。
WebPartZone 包含並提供組成頁面主要 UI 之 WebPart 控制項的整體版面配置。 每當您使用網頁元件控制項建立頁面時,請使用此區域。 頁面可以包含一或多個區域。
ConnectionsZone 包含 WebPartConnection 控制項,並提供用來管理連線的 UI。
WebPart (GenericWebPart) 轉譯主要 UI;大部分的網頁元件 UI 控制項都屬於此類別。 若要取得最大程式設計控制項,您可以建立衍生自基底 WebPart 控制項的自訂 Web 元件控制項。 您也可以使用現有的伺服器控制項、使用者控制項或自訂控制項作為網頁元件控制項。 每當這些控制項放在區域中時, WebPartManager 控制項會在執行時間自動將它們與 GenericWebPart 控制項包裝,讓您可以搭配網頁元件功能使用它們。
CatalogPart 包含使用者可以新增至頁面的可用網頁元件控制項清單。
WebPartConnection 在頁面上建立兩個網頁元件控制項之間的連線。 連線會將其中一個網頁元件控制項定義為數據 () 的提供者,另一個則定義為取用者。
EditorPart 做為特製化編輯器控制項的基類。
EditorPart 控制項 (AppearanceEditorPart、LayoutEditorPart、BehaviorEditorPart 和 PropertyGridEditorPart) 允許使用者在頁面上個人化 Web 元件 UI 控制項的各種層面

實驗室:建立網頁元件頁面

在此實驗室中,您將建立網頁元件頁面,以透過 ASP.NET 設定檔保存資訊。

使用網頁元件建立簡單頁面

在本逐步解說的這個部分中,您會建立使用網頁元件控制項來顯示靜態內容的頁面。 使用網頁元件的第一個步驟是建立具有兩個必要結構元素的頁面。 首先,網頁元件頁面需要 WebPartManager 控制項來追蹤及協調所有網頁元件控制項。 其次,網頁元件頁面需要一或多個區域,這些區域是包含 WebPart 或其他伺服器控制項的複合控制項,並佔用頁面的指定區域。

注意

您不需要執行任何動作即可啟用 Web 元件個人化;預設會針對網頁元件控制項集啟用它。 當您第一次在網站上執行網頁元件頁面時,ASP.NET 設定預設個人化提供者來儲存使用者個人化設定。 如需個人化的詳細資訊,請參閱 Web 元件個人化概觀。

建立包含網頁元件控制項的頁面

  1. 關閉預設頁面,並將新頁面新增至名為 WebPartsDemo.aspx 的網站。

  2. 切換至 [設計] 檢視。

  3. 從 [ 檢視 ] 功能表中,確定已選取 [非視覺控制項詳細 資料] 選項,讓您可以查看沒有 UI 的配置標記和控制項。

  4. 將插入點放在設計介面上的標籤之前 <div> ,然後按 ENTER 以新增一行。 將插入點放在新行字元之前,按一下功能表上的 [封鎖格式 ] 下拉式清單控制項,然後選取 [標題 1 ] 選項。 在標題中,新增文字 網頁元件示範頁面

  5. 從 [工具箱] 的 [WebParts ] 索引標籤中,將 WebPartManager 控制項拖曳到頁面上,將它放在新行字元和標記之前 <div>

    WebPartManager控制項不會轉譯任何輸出,因此它會顯示為設計工具介面上的灰色方塊。

  6. 將插入點放在標籤內 <div>

  7. 在 [ 版面配置 ] 功能表中,按一下 [ 插入資料表],然後建立具有一列和三個數據行的新資料表。 按一下 [儲存格屬性]按鈕,從[垂直對齊] 下拉式清單中選取頂端,按一下 [確定],然後再按一下 [確定] 以建立資料表。

  8. 將 WebPartZone 控制項拖曳至左側資料表資料行。 以滑鼠右鍵按一下 WebPartZone 控制項,選擇 [ 屬性],然後設定下列屬性:

    識別碼:SidebarZone

    HeaderText:提要欄

  9. 將第二個 WebPartZone 控制項拖曳到中間資料表資料行,並設定下列屬性:

    識別碼:MainZone

    HeaderText:Main

  10. 儲存檔案。

您的頁面現在有兩個不同的區域,您可以個別控制。 不過,兩個區域都沒有任何內容,因此建立內容是下一個步驟。 在本逐步解說中,您會使用只顯示靜態內容的網頁元件控制項。

網頁元件區域的版面配置是由 zonetemplate > 元素所 < 指定。 在區域範本內,您可以新增任何 ASP.NET 控制項,無論是自訂網頁元件控制項、使用者控制項或現有的伺服器控制項。 請注意,您在這裡使用的是標籤控制項,而且只是新增靜態文字。 當您將一般伺服器控制項放在 WebPartZone 區域中時,ASP.NET 會將控制項視為執行時間的 Web 元件控制項,這會在控制項上啟用網頁元件功能。

建立主要區域的內容

  1. [設計 ] 檢視中,將 [ 標籤 ] 控制項從 [工具箱] 的 [ 標準 ] 索引標籤拖曳到 識別碼屬性設定 為 MainZone 的區域內容區域。

  2. 切換至 [來源 ] 檢視。 請注意, < 已新增 zonetemplate > 元素,以將 Label 控制項包裝在 MainZone 中。

  3. 將名為 title 的屬性新增至 < asp:label > 元素,並將其值設定為 Content。 從 < asp:label > 元素中移除 Text=「Label」 屬性。 在 asp:label > 專案的開頭和結束記號 < 之間,新增一些文字,例如歡迎在一對 < h2 > 元素標籤內的首頁。 您的程式碼看起來應該如下所示。

    <asp:webpartzone id="MainZone" runat="server" headertext="Main">
        <zonetemplate>
            <asp:label id="Label1" runat="server" title="Content">
                <h2>Welcome to My Home Page</h2>
            </asp:label>
        </zonetemplate>
    </asp:webpartzone>
    
  4. 儲存檔案。

接下來,建立也可以新增至頁面做為網頁元件控制項的使用者控制項。

建立使用者控制項

  1. 將新的 Web 使用者控制項新增至您的網站,作為搜尋控制項。 取消選取將 原始程式碼放在個別檔案中的選項。 將它新增至與 WebPartsDemo.aspx 頁面相同的目錄中,並將它命名為 SearchUserControl.ascx。

    注意

    本逐步解說的使用者控制項不會實作實際的搜尋功能;它只會用來示範網頁元件功能。

  2. 切換至 [設計 ] 檢視。 從 [工具箱] 的 [ 標準 ] 索引標籤,將 TextBox 控制項拖曳至頁面。

  3. 將插入點放在您剛才新增的文字方塊之後,然後按 ENTER 以新增一行。

  4. 將按鈕控制項拖曳到您剛才新增文字方塊下方新行的頁面。

  5. 切換至 [來源 ] 檢視。 請確定使用者控制項的原始程式碼看起來像下列範例。

    <%@ control language="C#"
        classname="SearchUserControl" %>
    <asp:textbox runat="server"
      id=" TextBox1"></asp:textbox>
    <br />
    <asp:button runat="server"
      id=" Button1" text="Search" />
    
  6. 儲存並關閉檔案。

現在您可以將網頁元件控制項新增至提要欄位區域。 您要將兩個控制項新增至提要欄位區域,一個包含連結清單,另一個是您在上一個程式中建立的使用者控制項。 連結會新增為標準 標籤 伺服器控制項,類似于您為 Main 區域建立靜態文字的方式。 不過,雖然包含在使用者控制項中的個別伺服器控制項可以直接包含在區域中, (例如標籤控制項) ,在此情況下則不是。 相反地,它們是您在上一個程式中建立的使用者控制項的一部分。 這示範在使用者控制項中封裝您想要的任何控制項和額外功能的常見方式,然後將該區域中的控制項參考為網頁元件控制項。

在執行時間,Web 元件控制項集會將這兩個控制項包裝為 GenericWebPart 控制項。 當 GenericWebPart控制項包裝 Web 服務器控制項時,泛型元件控制項是父控制項,而且您可以透過父控制項的 ChildControl 屬性存取伺服器控制項。 這個泛型元件控制項的使用可讓標準 Web 服務器控制項擁有與衍生自 WebPart 類別之 Web 元件控制項相同的基本行為和屬性。

將網頁元件控制項新增至提要欄位區域

  1. 開啟 WebPartsDemo.aspx 頁面。

  2. 切換至 [設計 ] 檢視。

  3. 將您建立的使用者控制項頁面 SearchUserControl.ascx 從方案總管拖曳到識別碼屬性設定為 SidebarZone 的區域,並將其放在該處。

  4. 儲存 WebPartsDemo.aspx 頁面。

  5. 切換至 [來源 ] 檢視。

  6. 在 SidebarZone 的 < asp:webpartzone > 元素內,于使用者控制項的參考上方,新增 < 包含連結的 asp:label > 元素,如下列範例所示。 此外,將 Title 屬性新增至使用者控制項標籤,其值為 Search,如下所示。

    <asp:WebPartZone id="SidebarZone" runat="server"
                     headertext="Sidebar">
        <zonetemplate>
            <asp:label runat="server" id="linksPart" title="My Links">
                <a href="http://www.asp.net">ASP.NET site</a>
                <br />
                <a href="http://www.gotdotnet.com">GotDotNet</a>
                <br />
                <a href="http://www.contoso.com">Contoso.com</a>
                <br />
            </asp:label>
            <uc1:SearchUserControl id="searchPart"
              runat="server" title="Search" />
        </zonetemplate>
    </asp:WebPartZone>
    
  7. 儲存並關閉檔案。

現在您可以在瀏覽器中流覽至頁面,以測試頁面。 此頁面會顯示兩個區域。 下列螢幕擷取畫面顯示頁面。

具有兩個區域的網頁元件示範頁面

網頁元件 VS 逐步解說 1 螢幕擷取畫面

圖 3:網頁元件 VS 逐步解說 1 螢幕擷取畫面

在每個控制項的標題列中是向下箭號,可讓您存取可在控制項上執行的可用動作動詞功能表。 按一下其中一個控制項的動詞功能表,然後按一下 [最小化 動詞],並注意控制項最小化。 從動詞功能表按一下 [ 還原],控制項會返回其正常大小。

讓使用者編輯頁面和變更版面配置

網頁元件可讓使用者藉由將網頁元件控制項從一個區域拖曳到另一個區域,來變更網頁元件控制項的配置。 除了允許使用者將 WebPart 控制項從一個區域移到另一個區域之外,您還可以允許使用者編輯控制項的各種特性,包括其外觀、版面配置和行為。 Web 元件控制項集提供 WebPart 控制項的基本編輯功能。 雖然您不會在本逐步解說中這麼做,但您也可以建立自訂編輯器控制項,讓使用者編輯 WebPart 控制項的功能。 如同變更 WebPart 控制項的位置,編輯控制項的屬性依賴 ASP.NET 個人化來儲存使用者所做的變更。

在本逐步解說的這個部分中,您會新增使用者編輯頁面上任何 WebPart 控制項的基本特性的能力。 若要啟用這些功能,您可以將另一個自訂使用者控制項新增至頁面,以及 asp:editorzone > 元素和兩個 < 編輯控制項。

建立可啟用變更版面配置的使用者控制項

  1. 在 Visual Studio 的 [ 檔案 ] 功能表上,選取 [ 新增 ] 子功能表,然後按一下 [ 檔案] 選項。

  2. 在 [ 新增專案 ] 對話方塊中,選取 [Web 使用者控制項]。 將新檔案命名為 DisplayModeMenu.ascx。 取消選取將 原始程式碼放在個別檔案中的選項。

  3. 按一下 [新增] 以建立新的控制項。

  4. 切換至 [來源 ] 檢視。

  5. 移除新檔案中的所有現有程式碼,並貼上下列程式碼。 此使用者控制項程式碼會使用網頁元件控制項集的功能,讓頁面可以變更其檢視或顯示模式,也可讓您在處於特定顯示模式時變更頁面的實體外觀和版面配置。

    <%@ Control Language="C#" ClassName="DisplayModeMenuCS" %>
    
    <script runat="server">
    
        // Use a field to reference the current WebPartManager control.
        WebPartManager _manager;
        void Page_Init(object sender, EventArgs e) {
            Page.InitComplete += new EventHandler(InitComplete);
        }
        void InitComplete(object sender, System.EventArgs e) {
            _manager = WebPartManager.GetCurrentWebPartManager(Page);
            String browseModeName = WebPartManager.BrowseDisplayMode.Name;
            // Fill the drop-down list with the names of supported display modes.
            foreach (WebPartDisplayMode mode in
            _manager.SupportedDisplayModes) {
                String modeName = mode.Name;
                // Make sure a mode is enabled before adding it.
                if (mode.IsEnabled(_manager)) {
                    ListItem item = new ListItem(modeName, modeName);
                    DisplayModeDropdown.Items.Add(item);
                }
            }
            // If Shared scope is allowed for this user, display the
            // scope-switching UI and select the appropriate radio
            // button for the current user scope.
            if (_manager.Personalization.CanEnterSharedScope) {
                Panel2.Visible = true;
                if (_manager.Personalization.Scope ==
                PersonalizationScope.User)
                    RadioButton1.Checked = true;
                else
                    RadioButton2.Checked = true;
            }
        }
    
        // Change the page to the selected display mode.
        void DisplayModeDropdown_SelectedIndexChanged(object sender,
            EventArgs e) {
            String selectedMode = DisplayModeDropdown.SelectedValue;
            WebPartDisplayMode mode =
                _manager.SupportedDisplayModes[selectedMode];
            if (mode != null)
                _manager.DisplayMode = mode;
        }
        // Set the selected item equal to the current display mode.
        void Page_PreRender(object sender, EventArgs e) {
            ListItemCollection items = DisplayModeDropdown.Items;
            int selectedIndex =
            items.IndexOf(items.FindByText(_manager.DisplayMode.Name));
            DisplayModeDropdown.SelectedIndex = selectedIndex;
        }
        // Reset all of a user's personalization data for the page.
        protected void LinkButton1_Click(object sender, EventArgs e) {
            _manager.Personalization.ResetPersonalizationState();
        }
        // If not in User personalization scope, toggle into it.
        protected void RadioButton1_CheckedChanged(object sender, EventArgs e) {
            if (_manager.Personalization.Scope == PersonalizationScope.Shared)
                _manager.Personalization.ToggleScope();
        }
    
        // If not in Shared scope, and if user has permission, toggle
        // the scope.
        protected void RadioButton2_CheckedChanged(object sender,
        EventArgs e) {
            if (_manager.Personalization.CanEnterSharedScope &&
                _manager.Personalization.Scope == PersonalizationScope.User)
                _manager.Personalization.ToggleScope();
        }
    </script>
    
    <div>
        <asp:Panel ID="Panel1" runat="server"
          BorderWidth="1" Width="230" BackColor="lightgray"
            Font-Names="Verdana, Arial, Sans Serif">
            <asp:Label ID="Label1" runat="server"
              Text=" Display Mode" Font-Bold="true"
                Font-Size="8" Width="120" />
            <asp:DropDownList ID="DisplayModeDropdown"
              runat="server" AutoPostBack="true" Width="120"
                OnSelectedIndexChanged="DisplayModeDropdown_SelectedIndexChanged" />
            <asp:LinkButton ID="LinkButton1" runat="server"
                 Text="Reset User State"
                 ToolTip="Reset the current user's personalization data for the page."
                 Font-Size="8" OnClick="LinkButton1_Click" />
            <asp:Panel ID="Panel2" runat="server"
                GroupingText="Personalization Scope" Font-Bold="true"
                Font-Size="8" Visible="false">
                <asp:RadioButton ID="RadioButton1" runat="server"
                    Text="User" AutoPostBack="true"
                    GroupName="Scope"
                    OnCheckedChanged="RadioButton1_CheckedChanged" />
                <asp:RadioButton ID="RadioButton2" runat="server"
                    Text="Shared" AutoPostBack="true"
                    GroupName="Scope"
                    OnCheckedChanged="RadioButton2_CheckedChanged" />
            </asp:Panel>
        </asp:Panel>
    </div>
    
  6. 按一下工具列上的儲存圖示,或選取 [檔案] 功能表上的 [ 儲存 ],以儲存 案。

讓使用者變更版面配置

  1. 開啟 [WebPartsDemo.aspx] 頁面,然後切換至 [設計 ] 檢視。

  2. 將插入點放在您稍早新增的WebPartManager控制項之後的[設計] 檢視中。 在文字後面新增硬式傳回,使 WebPartManager 控制項後面有空白行。 將插入點放在空白行上。

  3. 將您剛才建立的使用者控制項拖曳 (檔案名為 DisplayModeMenu.ascx) 至 WebPartsDemo.aspx 頁面,並將它放在空白行上。

  4. 將 EditorZone 控制項從 [工具箱] 的 [WebParts ] 區段拖曳至 [WebPartsDemo.aspx] 頁面中剩餘的開啟資料表單元格。

  5. 從 [工具箱] 的 [WebParts ] 區段中,將 AppearanceEditorPart 控制項和 LayoutEditorPart 控制項拖曳至 EditorZone 控制項。

  6. 切換至 [來源 ] 檢視。 資料表單元格中產生的程式碼看起來應該類似下列程式碼。

    <td valign="top">
        <asp:EditorZone ID="EditorZone1" runat="server">
            <ZoneTemplate>
                <asp:AppearanceEditorPart ID="AppearanceEditorPart1"
                  runat="server" />
                <asp:LayoutEditorPart ID="LayoutEditorPart1"
                  runat="server" />
            </ZoneTemplate>
        </asp:EditorZone>
    </td>
    
  7. 儲存 WebPartsDemo.aspx 檔案。 您已建立使用者控制項,可讓您變更顯示模式和變更版面配置,而且您已參考主要網頁上的控制項。

您現在可以測試編輯頁面和變更版面配置的功能。

測試版面配置變更

  1. 在瀏覽器中載入頁面。
  2. 按一下 [ 顯示模式] 下拉式功能表,然後選取 [ 編輯]。 區域標題隨即顯示。
  3. 將 [ 我的連結 ] 控制項依標題列從 [側邊欄] 區域拖曳到 [主要] 區域的底部。 您的頁面看起來應該像下列螢幕擷取畫面。

網頁元件 VS 逐步解說 2 螢幕擷取畫面

圖 4:網頁元件 VS 逐步解說 2 螢幕擷取畫面

  1. 按一下 [ 顯示模式] 下拉式功能表,然後選取 [ 流覽]。 頁面會重新整理、區功能變數名稱稱消失,而 [我的連結 ] 控制項會保留在您放置的位置。

  2. 若要示範個人化是否正常運作,請關閉瀏覽器,然後再次載入頁面。 您所做的變更會儲存給未來的瀏覽器會話。

  3. 從 [ 顯示模式] 功能表中,選取 [ 編輯]。

    頁面上的每個控制項現在都會在其標題列中顯示向下箭號,其中包含動詞下拉式功能表。

  4. 按一下箭號,即可在 [ 我的連結 ] 控制項上顯示動詞功能表。 按一下 [編輯 動詞]。

    EditorZone控制項隨即出現,顯示您新增的 EditorPart 控制項。

  5. 在編輯控制項的 [外觀 ] 區段中,將 [ 標題 ] 變更為 [我的最愛],使用 [Chrome 類型 ] 下拉式清單選取 [ 僅限標題],然後按一下 [ 套用]。 下列螢幕擷取畫面顯示處於編輯模式的頁面。

編輯模式中的網頁元件示範頁面

網頁元件 VS 逐步解說 3 螢幕擷取畫面

圖 5:網頁元件 VS 逐步解說 3 螢幕擷取畫面

  1. 按一下 [ 顯示模式 ] 功能表,然後選取 [ 流覽 ] 以返回瀏覽模式。
  2. 控制項現在有更新的標題,沒有框線,如下列螢幕擷取畫面所示。

編輯的網頁元件示範頁面

網頁元件 VS 逐步解說 4 螢幕擷取畫面

圖 4:網頁元件 VS 逐步解說 4 螢幕擷取畫面

在執行時間新增網頁元件

您也可以允許使用者在執行時間將網頁元件控制項新增至其頁面。 若要這樣做,請使用網頁元件目錄來設定頁面,其中包含您想要提供給使用者的網頁元件控制項清單。

允許使用者在執行時間新增網頁元件

  1. 開啟 WebPartsDemo.aspx 頁面,然後切換至 [設計] 檢視。

  2. 從 [工具箱] 的 [WebParts ] 索引標籤中,將 CatalogZone 控制項拖曳到資料表右欄的 EditorZone 控制項下方。

    這兩個控制項都可以在相同的表格儲存格中,因為它們不會同時顯示。

  3. 在 [屬性] 窗格中,將字串 [新增網頁元件] 指派給 CatalogZone 控制項的 HeaderText 屬性。

  4. 從 [工具箱] 的 [WebParts ] 區段,將 DeclarativeCatalogPart 控制項拖曳至 CatalogZone 控制項的內容區域。

  5. 按一下 DeclarativeCatalogPart 控制項右上角的箭號,以公開其 [工作] 功能表,然後選取 [ 編輯範本]。

  6. 從 [工具箱] 的 [標準] 區段,將FileUpload控制項和行事曆控制項拖曳至DeclarativeCatalogPart控制項的WebPartsTemplate區段。

  7. 切換至 [來源 ] 檢視。 檢查 asp:catalogzone > 專案的原始程式碼 < 。 請注意,DeclarativeCatalogPart控制項包含 webpartstemplate > 元素,其中包含兩個 < 封閉的伺服器控制項,您將能夠從目錄新增至頁面。

  8. 使用下列程式碼範例中針對每個標題顯示的字串值,將 Title 屬性新增至您新增至目錄的每個控制項。 雖然標題不是您在設計階段通常可以在這兩個伺服器控制項上設定的屬性,但當使用者在執行時間從類別目錄將這些控制項新增至 WebPartZone 區域時,它們都會以 GenericWebPart 控制項包裝。 這可讓它們做為網頁元件控制項,因此能夠顯示標題。

    DeclarativeCatalogPart控制項中包含的兩個控制項的程式碼應該如下所示。

    <asp:DeclarativeCatalogPart ID="DeclarativeCatalogPart1" runat="server">
        <WebPartsTemplate>
            <asp:Calendar ID="Calendar1" runat="server" title="My Calendar" />
            <asp:FileUpload ID="FileUpload1" runat="server" title="Upload Files" />
        </WebPartsTemplate>
    </asp:DeclarativeCatalogPart>
    
  9. 儲存網頁。

您現在可以測試目錄。

測試網頁元件目錄

  1. 在瀏覽器中載入頁面。

  2. 按一下 [ 顯示模式 ] 下拉式功能表,然後選取 [ 目錄]。

    標題為 [新增網頁元件 ] 的目錄隨即顯示。

  3. 將 [ 我的最愛] 控制項從主要區域拖曳回側邊欄區域的頂端,然後將它放在該處。

  4. 在 [ 新增網頁元件 ] 目錄中,選取這兩個核取方塊,然後從包含可用區域的下拉式清單中選取 [Main ]。

  5. 按一下目錄中的 [ 新增 ]。 控制項會新增至主要區域。 如果您想要,您可以將多個控制項實例從類別目錄新增至頁面。

    下列螢幕擷取畫面顯示頁面,其中包含檔案上傳控制項和主要區域中的行事曆。

從目錄新增至主要區域的控制項

圖 5:從目錄 6 新增至主要區域的控制項。按一下 [ 顯示模式 ] 下拉式功能表,然後選取 [ 流覽]。 目錄會消失,並重新整理頁面。 7.關閉瀏覽器。 再次載入頁面。 您所做的變更會保存。