首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

ASP.NET 自訂 Web 控制項開發實戰:使用 C# 建立可重用、預編譯的導航列元件

     編輯:關於C語言

為什麼選擇 C# Web 控制項而非 User Control (.ascx)?

特性Web 控制項 (.cs + DLL)User Control (.ascx)
程式碼與標記分離完全分離 (C# 類別)混合在 .ascx 檔案
預編譯編譯為 DLL,無原始碼部署需部署 .ascx 原始碼
工具箱整合支援設計工具、屬性視窗不支援
跨專案重用參考 DLL 即可需複製 .ascx 檔案
設計時支援完整設計時體驗有限
版本控制組件版本、強式名稱檔案層級

專案結構

MyNavBar.sln
├── MyNavBar (類別庫專案)
│   ├── NavBar.cs          // 核心控制項類別
│   └── Properties/AssemblyInfo.cs
└── WebApplication (測試網站)
    ├── Default.aspx
    └── bin/MyNavBar.dll   // 參考輸出

核心控制項實作:NavBar.cs

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections.Generic;

namespace MyNavBar
{
    /// 
    /// 動態產生 Yahoo 風格麵包屑導航列
    /// 
    [ToolboxData("<{0}:NavBar runat=server>")]
    public class NavBar : WebControl
    {
        // === 可自訂屬性 ===
        private string _separator = ">";
        private int _leftPadding = 1;
        private int _rightPadding = 3;

        /// 分隔符號 HTML
        [Category("Appearance")]
        [DefaultValue(">")]
        public string Separator
        {
            get => _separator;
            set => _separator = value ?? ">";
        }

        /// 分隔符號左側空白數
        [Category("Appearance")]
        [DefaultValue(1)]
        public int LeftPadding
        {
            get => _leftPadding;
            set => _leftPadding = Math.Max(0, value);
        }

        /// 分隔符號右側空白數
        [Category("Appearance")]
        [DefaultValue(3)]
        public int RightPadding
        {
            get => _rightPadding;
            set => _rightPadding = Math.Max(0, value);
        }

        // === 核心邏輯:建立子控制項 ===
        protected override void CreateChildControls()
        {
            Controls.Clear(); // 確保重新建立時不重複

            // 1. 建立分隔符號標籤 (共用實例)
            var separatorLabel = new Label
            {
                Text = new string(' ', _leftPadding) + _separator + new string(' ', _rightPadding)
            };

            // 2. 首頁連結 (固定)
            var homeLink = new HyperLink
            {
                Text = "Home",
                NavigateUrl = "~/"
            };
            Controls.Add(homeLink);

            // 3. 解析目前請求路徑,動態產生中間層級連結
            string[] pathSegments = Page.Request.Path.Split('/');
            // 範例:/folder1/folder2/page.aspx → ["", "folder1", "folder2", "page.aspx"]
            
            string accumulatedPath = "";
            for (int i = 1; i < pathSegments.Length - 1; i++) // 排除首個空字串與檔名
            {
                string segment = pathSegments[i];
                accumulatedPath += "/" + segment;

                // 加入分隔符號
                Controls.Add(new Label { Text = separatorLabel.Text });

                // 加入層級連結
                var link = new HyperLink
                {
                    Text = CapitalizeFirst(segment),
                    NavigateUrl = accumulatedPath + "/" // 目錄需以 / 結尾,依賴 IIS 預設文件
                };
                Controls.Add(link);
            }

            // 4. 最後一層:目前頁面標題 (非連結)
            if (pathSegments.Length > 1)
            {
                Controls.Add(new Label { Text = separatorLabel.Text });
                string pageName = pathSegments[pathSegments.Length - 1];
                // 移除副檔名
                int dotIndex = pageName.LastIndexOf('.');
                if (dotIndex > 0) pageName = pageName.Substring(0, dotIndex);
                Controls.Add(new Label 
                { 
                    Text = CapitalizeFirst(pageName),
                    CssClass = "current-page"
                });
            }
        }

        private static string CapitalizeFirst(string input)
        {
            if (string.IsNullOrEmpty(input)) return input;
            return char.ToUpper(input[0]) + input.Substring(1).ToLower();
        }

        // === 渲染輸出 ===
        protected override void Render(HtmlTextWriter writer)
        {
            // 確保子控制項已建立
            EnsureChildControls();
            
            // 包裝容器 (可選)
            writer.AddAttribute(HtmlTextWriterAttribute.Class, "navbar-container");
            writer.RenderBeginTag(HtmlTextWriterTag.Div);
            
            base.Render(writer); // 渲染所有子控制項
            
            writer.RenderEndTag(); // 
} } }

編譯與部署

  1. 建置類別庫專案 → 產出 MyNavBar.dll
  2. 將 DLL 複製至網站專案 bin 目錄
  3. 或在網站專案中加入專案參考

ASPX 頁面使用方式

1. 註冊標籤前綴 (單頁)

```aspx <%@ Register TagPrefix="MyBar" Namespace="MyNavBar" Assembly="MyNavBar" %> ```

2. 網頁.config 全域註冊 (全站)

```xml ```

3. 頁面中使用

```aspx ```

進階擴充:支援頁面標題、樣式、資料繫結

// 擴充屬性
[Category("Behavior")]
[DefaultValue(false)]
public bool UsePageTitle { get; set; } = false;

[Category("Appearance")]
public string CurrentPageCssClass { get; set; } = "current-page";

[Category("Appearance")]
public string LinkCssClass { get; set; } = "nav-link";

[Category("Appearance")]
public string SeparatorCssClass { get; set; } = "nav-separator";

// 在 CreateChildControls 中應用
var link = new HyperLink
{
    Text = CapitalizeFirst(segment),
    NavigateUrl = accumulatedPath + "/",
    CssClass = LinkCssClass
};

// 目前頁面
var currentLabel = new Label
{
    Text = UsePageTitle ? Page.Title : CapitalizeFirst(pageName),
    CssClass = CurrentPageCssClass
};

// 分隔符號
var sepLabel = new Label
{
    Text = separatorLabel.Text,
    CssClass = SeparatorCssClass
};

CSS 樣式範例

```css .navbar-container { font-family: Arial, sans-serif; font-size: 14px; padding: 10px; } .nav-link { color: #0066cc; text-decoration: none; } .nav-link:hover { text-decoration: underline; } .nav-separator { color: #999; } .current-page { font-weight: bold; color: #333; } ```

設計時支援:ToolboxBitmap 與 DesignTimeHtml

[ToolboxBitmap(typeof(NavBar), "NavBar.bmp")] // 16x16 圖示嵌入資源
public class NavBar : WebControl
{
    // 設計工具顯示預覽
    public override string DesignModeHtml
    {
        get
        {
            return "
" + "[NavBar: Home > Folder > Page] " + "
"; } } }

測試與驗證

  1. 建立測試網站,加入參考 MyNavBar.dll
  2. 建立多層目錄結構:/Products/Books/Detail.aspx
  3. 在母版頁或內容頁放入 ``
  4. 瀏覽各層級頁面,驗證導航連結正確性

總結

C# 自訂 Web 控制項提供:完整封裝、預編譯部署、設計工具整合、屬性化配置、跨專案重用。核心步驟:繼承 WebControl → 定義屬性 → 覆寫 CreateChildControls 建立子控制項樹 → 覆寫 Render 控制輸出 → 編譯 DLL → 註冊標籤前綴使用。掌握此模式,即能建構企業級可重用 UI 元件庫。

  1. 上一篇文章:
  2. 下一篇文章:
欄目導航
Copyright © 程式碼之家 All Rights Reserved