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

ASP.NET 實作下拉框二級聯動元件:縣市/鄉鎮市區級聯 UserControl 完整程式碼

     編輯:關於ASP.NET

需求場景

表單需「縣市 → 鄉鎮市區」二級下拉聯動。封裝為 `UserControl` (`.ascx`),支援 `SelectedValue` 雙向繫結,可重複使用於多個頁面。

UserControl 完整程式碼

Area.ascx (標記)

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Area.ascx.cs" Inherits="Area" %>
<asp:DropDownList ID="ddlProvince" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ddlProvince_SelectedIndexChanged"></asp:DropDownList>
<asp:DropDownList ID="ddlCity" runat="server"></asp:DropDownList>

Area.ascx.cs (後台)

using System;
using System.Data;
using System.Data.SqlClient;
using System.Web.UI.WebControls;

public partial class Area : System.Web.UI.UserControl
{
    // 對外屬性:雙向繫結 SelectedValue
    public string ProvinceValue
    {
        get => ddlProvince.SelectedValue;
        set
        {
            ddlProvince.ClearSelection();
            var item = ddlProvince.Items.FindByValue(value);
            if (item != null) item.Selected = true;
        }
    }

    public string CityValue
    {
        get => ddlCity.SelectedValue;
        set
        {
            ddlCity.ClearSelection();
            var item = ddlCity.Items.FindByValue(value);
            if (item != null) item.Selected = true;
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            BindProvinces();
            ddlCity.Items.Insert(0, new ListItem("- 請選擇鄉鎮市區 -", ""));
        }
    }

    private void BindProvinces()
    {
        using (var conn = new SqlConnection(DbHelper.ConnectionString))
        using (var cmd = new SqlCommand("SELECT ProvinceCode, ProvinceName FROM Provinces ORDER BY DisplayOrder", conn))
        {
            conn.Open();
            ddlProvince.DataSource = cmd.ExecuteReader();
            ddlProvince.DataTextField = "ProvinceName";
            ddlProvince.DataValueField = "ProvinceCode";
            ddlProvince.DataBind();
            ddlProvince.Items.Insert(0, new ListItem("- 請選擇縣市 -", ""));
        }
    }

    protected void ddlProvince_SelectedIndexChanged(object sender, EventArgs e)
    {
        ddlCity.Items.Clear();
        string provinceCode = ddlProvince.SelectedValue;
        if (!string.IsNullOrEmpty(provinceCode))
        {
            using (var conn = new SqlConnection(DbHelper.ConnectionString))
            using (var cmd = new SqlCommand("SELECT CityCode, CityName FROM Cities WHERE ProvinceCode=@ProvinceCode ORDER BY DisplayOrder", conn))
            {
                cmd.Parameters.AddWithValue("@ProvinceCode", provinceCode);
                conn.Open();
                ddlCity.DataSource = cmd.ExecuteReader();
                ddlCity.DataTextField = "CityName";
                ddlCity.DataValueField = "CityCode";
                ddlCity.DataBind();
            }
        }
        ddlCity.Items.Insert(0, new ListItem("- 請選擇鄉鎮市區 -", ""));
    }
}

資料庫結構建議

CREATE TABLE Provinces (
    ProvinceCode CHAR(5) PRIMARY KEY,  -- 如 'TW-TPQ' (台北市)
    ProvinceName NVARCHAR(50) NOT NULL,
    DisplayOrder INT DEFAULT 0
);

CREATE TABLE Cities (
    CityCode CHAR(8) PRIMARY KEY,      -- 如 'TW-TPQ-ZH' (中正區)
    ProvinceCode CHAR(5) NOT NULL REFERENCES Provinces(ProvinceCode),
    CityName NVARCHAR(50) NOT NULL,
    DisplayOrder INT DEFAULT 0
);

使用方式

<%@ Register TagPrefix="uc" TagName="Area" Src="~/Controls/Area.ascx" %>

<uc:Area ID="ucArea" runat="server" />

<asp:Button ID="btnSave" runat="server" Text="儲存" OnClick="btnSave_Click" />
protected void btnSave_Click(object sender, EventArgs e)
{
    string province = ucArea.ProvinceValue;
    string city = ucArea.CityValue;
    // 存入資料庫...
}

進階擴充

  • 三級聯動**:加入 `ddlDistrict` (村里),邏輯相同,`ddlCity_SelectedIndexChanged` 觸發載入。
  • 資料快取**:縣市資料極少變動,`Page_Load` 讀取時優先從 `Cache["Provinces"]` 取得,減少 DB 連線。
  • 前端 AJAX 版本**:`ddlProvince` 變更時呼叫 `$.getJSON("/api/cities?province=" + val)` 更新 `ddlCity`,無需 Postback,體驗更佳。
  • 驗證整合**:實作 `IValidator` 或配合 `CustomValidator` 確保使用者已選擇有效縣市與鄉鎮。

總結

將二級下拉聯動封裝為 `UserControl`,暴露 `ProvinceValue`/`CityValue` 屬性支援雙向繫結,配合參數化查詢與資料快取,即得一個可重用、安全、高效能的地址選擇元件。後續可依專案需求擴充為三級聯動或 AJAX 版本。

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