ASP.NET Web Forms 內建的 <asp:CheckBoxList> 預設為單欄垂直排列。當選項較多(如權限群組、興趣標籤)時,單欄會佔用過多垂直空間。本文示範如何以 RepeatLayout="Table" 搭配 RepeatColumns="2"、RepeatDirection="Horizontal" 快速實現兩欄水平排版,並以 CSS 微調間距、最後用 jQuery 取得使用者勾選的標籤文字。
<asp:CheckBoxList ID="DDLGroups" runat="server"
RepeatLayout="Table"
RepeatColumns="2"
RepeatDirection="Horizontal"
CssClass="chk-group">
</asp:CheckBoxList>
屬性說明:
RepeatLayout="Table":輸出 <table><tr><td> 結構,方便 CSS 控制欄寬。RepeatColumns="2":固定兩欄。RepeatDirection="Horizontal":先填滿第一列再換行,符合左→右閱讀習慣。CssClass="chk-group":統一套用樣式,避免內嵌 style 污染標記。.chk-group {
border-collapse: collapse;
line-height: 1.6;
}
.chk-group td {
width: 300px; /* 固定欄寬,防止長標籤撐破版面 */
border: 1px solid #e0e8f0; /* 淺色邊框輔助對齊,正式上線可移除 */
padding-left: 8px;
vertical-align: middle;
}
.chk-group input[type="checkbox"] {
margin-right: 6px;
transform: scale(1.1); /* 略微放大勾選框,提升可點擊區域 */
}
.chk-group label {
cursor: pointer;
user-select: none;
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var groups = new List<GroupItem> {
new GroupItem { Id = 1, Name = "系統管理員" },
new GroupItem { Id = 2, Name = "內容編輯" },
new GroupItem { Id = 3, Name = "行銷專員" },
new GroupItem { Id = 4, Name = "客服人員" },
new GroupItem { Id = 5, Name = "財務審核" },
new GroupItem { Id = 6, Name = "開發工程師" }
};
DDLGroups.DataSource = groups;
DDLGroups.DataTextField = "Name";
DDLGroups.DataValueField = "Id";
DDLGroups.DataBind();
}
}
public class GroupItem { public int Id { get; set; } public string Name { get; set; } }
// 取得所有被勾選的 label 文字,組成陣列
var selectedNames = $("#DDLGroups input:checkbox:checked")
.map(function () { return $(this).next("label").text().trim(); })
.get();
// 若需包含 value(後端 ID)
var selectedItems = $("#DDLGroups input:checkbox:checked")
.map(function () {
return { id: this.value, name: $(this).next("label").text().trim() };
})
.get();
console.log("勾選名稱:", selectedNames.join(", "));
console.log("完整物件:", selectedItems);
關鍵選取器說明:#DDLGroups input:checkbox:checked精準鎖定該 CheckBoxList 內被勾選的<input type="checkbox">;.next("label")取得緊鄰的<label>(ASP.NET 自動產生結構為<input><label>文字</label>)。
| 現象 | 原因 | 解決方式 |
|---|---|---|
| 欄位寬度不一致 | 長文字撐開 td | CSS 設定 table-layout: fixed; width: 100%; 配合 td { width: 50%; } |
| jQuery 取不到 label 文字 | ASP.NET 4.0+ 預設 RenderMode 可能不同 | 用瀏覽器 F12 檢查實際 DOM 結構,調整 .next() 或 .parent().find("label") |
| PostBack 後勾選消失 | ViewState 未啟用或資料重繫覆蓋 | 確認 EnableViewState="true",並在 !IsPostBack 才 DataBind |
| 需求 RWD 斷點 | 手機版雙欄過擁擠 | 加入 @media (max-width: 576px) { .chk-group td { width: 100%; display: block; } } |
若專案已遷移至 ASP.NET Core 或偏好純 HTML 控制,建議改用 <asp:Repeater> 或 Razor foreach 搭配 CSS Grid:
<div class="chk-grid">
<% foreach (var g in Model.Groups) { %>
<label>
<input type="checkbox" name="groupIds" value="<%= g.Id %>" />
<span><%= g.Name %></span>
</label>
<% } %>
</div>
.chk-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
@media (max-width: 576px) { .chk-grid { grid-template-columns: 1fr; } }
透過 RepeatLayout="Table"、RepeatColumns="2"、RepeatDirection="Horizontal" 三個屬性組合,加上少量 CSS 即可快速完成 CheckBoxList 兩欄水平排版。搭配 jQuery 取值技巧,滿足多數表單多選需求。若專案追求更高彈性與前端現代化,建議逐步改用 Repeater 或前端框架(Vue/React/Blazor)實作。