ASP.NET 2.0 將 SharePoint 成熟的 Web Parts 架構引入標準 ASP.NET,提供網頁區域劃分、拖曳佈局、編輯/目錄/連線模式、使用者個人化儲存等功能。本文系統介紹核心控制項、頁面結構、模式切換與實作範例。
Web Parts 頁面由 區域 組成,每個區域可包含一或多個 WebPart 控制項。使用者可在執行時拖曳調整位置、隱藏/最大化/編輯屬性,設定自動儲存至個人化資料庫(預設 SQL Express)。
| 控制項 | 層級 | 功能 | 可見性 |
|---|---|---|---|
| WebPartManager | 最上層(每頁僅一個) | 管理個人化狀態、協調 WebParts 與區域通訊、模式切換 | 不可見 |
| WebPartZone | 區域容器 | 承載 WebPart 控制項,定義版面區域(可多個) | 可見(設計時) |
| WebPart / 任意 Server Control | 內容單元 | 實際功能單元(GridView、Calendar、自訂 UserControl) | 可見 |
| CatalogZone | 目錄區域 | 「目錄模式」顯示,讓使用者從預定清單新增 WebPart | 僅目錄模式可見 |
| ConnectionZone | 連線區域 | 「連線模式」顯示,建立 WebPart 間資料傳遞(Provider/Consumer) | 僅連線模式可見 |
| EditorZone | 編輯區域 | 「編輯模式」顯示,編輯 WebPart 屬性(Appearance、Behavior、Custom) | 僅編輯模式可見 |
<%@ Page Language="C#" MasterPageFile="~/Site.master" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<asp:WebPartManager ID="WebPartManager1" runat="server" />
<table style="width:100%;">
<tr>
<td style="width:70%;">
<asp:WebPartZone ID="MainZone" runat="server" HeaderText="主要區域">
<ZoneTemplate>
<asp:Calendar ID="Calendar1" runat="server" Title="行事曆" />
<asp:BulletedList ID="BulletList1" runat="server" Title="待辦事項"
DisplayMode="HyperLink" DataSourceID="SqlDataSource1" DataTextField="Title" DataValueField="Url" />
</ZoneTemplate>
</asp:WebPartZone>
</td>
<td style="width:30%;">
<asp:WebPartZone ID="SideZone" runat="server" HeaderText="側邊欄">
<ZoneTemplate>
<asp:LoginView ID="LoginView1" runat="server" Title="登入狀態" />
</ZoneTemplate>
</asp:WebPartZone>
</td>
</tr>
</table>
<!-- 模式切換 UI -->
<asp:DropDownList ID="ddlMode" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ddlMode_SelectedIndexChanged">
<asp:ListItem Text="瀏覽模式" Value="Browse" />
<asp:ListItem Text="設計模式" Value="Design" />
<asp:ListItem Text="編輯模式" Value="Edit" />
<asp:ListItem Text="目錄模式" Value="Catalog" />
<asp:ListItem Text="連線模式" Value="Connect" />
</asp:DropDownList>
</asp:Content>
protected void ddlMode_SelectedIndexChanged(object sender, EventArgs e)
{
WebPartDisplayMode mode = WebPartManager1.SupportedDisplayModes
.Cast<WebPartDisplayMode>()
.FirstOrDefault(m => m.Name == ddlMode.SelectedValue);
if (mode != null)
WebPartManager1.DisplayMode = mode;
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
ddlMode.SelectedValue = WebPartManager1.DisplayMode.Name;
}
EditorZone 中的編輯控制項(AppearanceEditorPart、LayoutEditorPart、PropertyGridEditorPart、自訂 EditorPart)。CatalogZone,使用者可從 DeclarativeCatalogPart、PageCatalogPart、ImportCatalogPart 選擇新增 WebPart。ConnectionZone,建立 Provider(資料來源)與 Consumer(資料消費者)WebPart 間連線,實現主從聯動。<system.web>
<webParts>
<personalization defaultProvider="SqlPersonalizationProvider">
<providers>
<add name="SqlPersonalizationProvider"
type="System.Web.UI.WebControls.WebParts.SqlPersonalizationProvider"
connectionStringName="LocalSqlServer" />
</providers>
<authorization>
<allow users="*" verbs="enterSharedScope" /> <!-- 允許匿名用戶進入共享範圍 -->
<allow users="*" verbs="modifyState" /> <!-- 允許修改個人化狀態 -->
</authorization>
</personalization>
</webParts>
</system.web>
using System.Web.UI.WebControls.WebParts;
public class MyCustomWebPart : WebPart
{
[Personalizable(PersonalizationScope.User)]
[WebBrowsable(true)]
[WebDisplayName("顯示筆數")]
[WebDescription("設定列表顯示幾筆資料")]
public int DisplayCount { get; set; } = 10;
protected override void RenderContents(HtmlTextWriter writer)
{
writer.Write($"顯示前 {DisplayCount} 筆資料...");
// 實際資料繫結邏輯
}
}
註冊至頁面:<%@ Register TagPrefix="custom" Namespace="MyControls" Assembly="MyAssembly" %>,再放入 ZoneTemplate。
<asp:WebPartConnection>,編譯期決定,效能佳。ConnectionZone 由使用者建立,彈性高。ASP.NET Core 無內建 Web Parts。現代替代方案:
GridStack.js、Vue Grid Layout、React Grid Layout 實現儀表板拖曳。Web Parts 是 ASP.NET 2.0 時代極具野心的功能,雖未如 SharePoint 般普及,但其「區域化佈局、模式化操作、個人化持久化」設計思想深影響後來的入口網站、儀表板開發框架。維護舊專案時理解其生命週期與個人化提供者機制至關重要。