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

ASP.NET RadioButtonList 動態繫結資料並觸發選擇變更事件實作

     編輯:ASP.NET 基礎

RadioButtonList 是單選按鈕群組的伺服器控制項,常用於「分類篩選」等互動場景。本文示範如何在 Page_Load 動態從資料庫繫結選項,並配合 AutoPostBack 即時觸發 SelectedIndexChanged 事件重新查詢資料,採用三層架構(BLL/DAL)完整範例。

🎯 核心設定三要素

  1. AutoPostBack="true":選擇變更時自動回傳
  2. OnSelectedIndexChanged="RadioButtonList1_SelectedIndexChanged":指定事件處理器
  3. DataTextField/DataValueField:繫結顯示文字與實際值

🖥️ 前端宣告


💻 後端完整實作

1. 頁面類別

public partial class Technology : System.Web.UI.Page
{
    private string _depId;

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            AspNetPager1.PageSize = 10;
            _depId = Request.QueryString["Id"] ?? string.Empty;
            BindDepartmentList();   // 步驟 1:繫結單選按鈕選項
            BindTechnologyList();   // 步驟 2:依預設/傳入條件查詢資料
        }
    }

    /// 繫結部門下拉選項(RadioButtonList)
    private void BindDepartmentList()
    {
        var bll = new ExpertInfoBLL();
        DataTable dt = bll.GetDepInfo(); // 取得 Id, Name

        // 方式一:手動加入 Items(保留舊資料時有用)
        foreach (DataRow dr in dt.Rows)
            RadioButtonList1.Items.Add(dr["Name"].ToString());

        // 方式二:標準資料繫結(推薦)
        RadioButtonList1.DataSource = dt;
        RadioButtonList1.DataTextField = "Name";
        RadioButtonList1.DataValueField = "Id";
        RadioButtonList1.RepeatDirection = RepeatDirection.Horizontal;
        RadioButtonList1.DataBind();
    }

    /// 查詢並繫結技術文章列表
    private void BindTechnologyList(string depId = "")
    {
        var bll = new TechnologyBLL();
        string where = "1=1";
        if (!string.IsNullOrEmpty(depId))
            where += $" AND a.Depinfo_Id = '{depId}'";

        AspNetPager1.RecordCount = bll.GetCountList(where);
        DataTable dt = bll.GetList(
            (AspNetPager1.CurrentPageIndex - 1) * AspNetPager1.PageSize,
            AspNetPager1.PageSize, where, "CreateTime");
        Repeater1.DataSource = dt;
        Repeater1.DataBind();
    }

    /// 分頁事件
    protected void AspNetPager1_PageChanged(object sender, EventArgs e)
    {
        BindTechnologyList(_depId);
    }

    /// RadioButtonList 選擇變更事件
    protected void RadioButtonList1_SelectedIndexChanged(object sender, EventArgs e)
    {
        _depId = RadioButtonList1.SelectedValue; // 取得所選部門 Id
        BindTechnologyList(_depId);            // 重新查詢並繫結
    }
}

2. BLL 層

// TechnologyBLL.cs
public class TechnologyBLL
{
    private readonly TechnologyDAL _dal = new TechnologyDAL();

    public DataTable GetList(int start, int size, string where, string orderBy)
        => _dal.GetList(start, size, where, orderBy);

    public int GetCountList(string where) => _dal.GetCountList(where);

    public DataTable GetModel(string id) => _dal.GetModel(id);
    public DataTable GetPicture(string id) => _dal.GetPicture(id);
}

// ExpertInfoBLL.cs
public class ExpertInfoBLL
{
    private readonly ExpertInfoDAL _dal = new ExpertInfoDAL();
    public DataTable GetDepInfo() => _dal.GetDepInfo();
}

3. DAL 層

// TechnologyDAL.cs
public class TechnologyDAL
{
    public DataTable GetList(int start, int size, string where, string orderBy)
    {
        string sql = $@"SELECT a.TechnologyId, a.TechnologyName, a.Summarize, a.Effect, 
                       a.MainPoint, a.AppropriateArea, a.Attention, a.CreateTime, a.CreatUser, 
                       a.UpdateTime, b.Name 
                       FROM Technology a LEFT JOIN Sys_DepInfo b ON a.Depinfo_Id = b.Id
                       WHERE a.IsActive = '1' AND {where}";

        var sp = new[]
        {
            new SqlParameter("@intStartIndex", start),
            new SqlParameter("@intPageSize", size),
            new SqlParameter("@varStatement", sql),
            new SqlParameter("@varSortExpression", orderBy + " DESC")
        };
        return SqlDbHelper.GetDataSet("proc_CommonPagerWithStatement", sp, SqlDbHelper.Connection);
    }

    public int GetCountList(string where)
    {
        string sql = $@"SELECT COUNT(TechnologyId) FROM (
                       SELECT a.TechnologyId FROM Technology a LEFT JOIN Sys_DepInfo b ON a.Depinfo_Id = b.Id
                       WHERE a.IsActive = '1' AND {where}) AS c";
        var dt = SqlDbHelper.GetDataTable(sql);
        return dt.Rows.Count > 0 ? int.Parse(dt.Rows[0][0].ToString()) : 0;
    }
    // GetModel, GetPicture 略...
}

// ExpertInfoDAL.cs
public class ExpertInfoDAL
{
    public DataTable GetDepInfo()
    {
        string sql = "SELECT Id, Name FROM dbo.Sys_DepInfo WHERE Is_Active='1' AND DepinfoType='1'";
        return SqlDbHelper.GetDataTable(sql);
    }
}

🔄 完整互動流程

  1. 頁面首次載入 → BindDepartmentList() 繫結部門 → BindTechnologyList() 顯示預設部門文章
  2. 使用者點選其他部門單選按鈕 → 瀏覽器 PostBack
  3. 觸發 RadioButtonList1_SelectedIndexChanged → 取得 SelectedValue
  4. 呼叫 BindTechnologyList(depId) → 重新查詢 → Repeater1.DataBind() 更新畫面
  5. 分頁控制項 AspNetPager 同樣攜帶當前 _depId 查詢

⚠️ 常見坑點與解決

問題原因解決
事件不觸發未設定 AutoPostBack="true"務必加上屬性
重複繫結導致選項疊加PostBack 時再次執行 DataBind()包在 if (!IsPostBack) 區塊
SelectedValue 為空DataValueField 拼錯或資料來源無該欄位檢查 SQL 查詢欄位名稱
分頁後條件遺失頁面變數 _depId 未保存用 ViewState["DepId"] 或隱藏欄位保存

🎨 進階美化建議

  • 使用 CssClass 套用 Bootstrap `btn-group-toggle` 樣式,變身美觀按鈕組
  • 加入 `RepeatLayout="Flow"` 移除預設 Table 佈局,配合 CSS Flexbox 排版
  • 前端加入 `data-dep-id` 屬性,配合 jQuery/Ajax 實現無刷新局部更新

掌握此模式,即可快速建構「分類篩選 → 即時刷新列表」的經典互動體驗,廣泛適用於新聞分類、商品篩選、知識庫標籤等場景。

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