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

ASP.NET Calendar 日曆控制項完整應用:多重選取模式、TGIF 全選星期五、日期區間選取與自訂樣式

     編輯:ASP.NET 基礎

Calendar 控制項核心屬性

屬性說明
SelectionModeDay(單日)、DayWeek(週)、DayWeekMonth(月)、None(不可選)
SelectedDate單一選取日期(DateTime)
SelectedDates多重選取集合(SelectedDatesCollection)
VisibleDate目前顯示的月份(不影響選取)
TodaysDate今日日期(唯讀)
FirstDayOfWeek週首日(預設 Sunday)
ShowGridLines顯示格線

前端頁面完整佈局(含下拉選月、TGIF、區間選取)

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CalendarDemo.aspx.cs" Inherits="Demo.CalendarDemo" %>
<!DOCTYPE html>
<html>
<head><title>Calendar 進階示範</title></head>
<body>
    <form id="form1" runat="server">
        <asp:Calendar ID="calMain" runat="server" 
            SelectionMode="DayWeekMonth" 
            OnSelectionChanged="calMain_SelectionChanged"
            OnDayRender="calMain_DayRender"
            OnVisibleMonthChanged="calMain_VisibleMonthChanged"
            DayNameFormat="FirstTwoLetters"
            NextPrevFormat="FullMonth"
            CellPadding="4" CellSpacing="1"
            BackColor="White" BorderColor="#CCCCCC" BorderWidth="1px">
            <DayHeaderStyle BackColor="#006699" ForeColor="White" Font-Bold="True" />
            <TitleStyle BackColor="#006699" ForeColor="White" Font-Bold="True" Font-Size="14pt" />
            <TodayDayStyle BackColor="#FFFF99" BorderColor="Red" BorderStyle="Solid" BorderWidth="2px" />
            <SelectedDayStyle BackColor="#006699" ForeColor="White" Font-Bold="True" />
            <WeekendDayStyle BackColor="#F7F7F7" />
            <OtherMonthDayStyle ForeColor="#CCCCCC" />
        </asp:Calendar>

        <br />
        <asp:Label ID="lblToday" runat="server" />
        <br />
        <asp:Label ID="lblSelected" runat="server" />
        <br />
        <asp:Label ID="lblCount" runat="server" />

        <hr />
        <table>
            <tr>
                <td>選擇月份:</td>
                <td>
                    <asp:DropDownList ID="ddlMonth" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ddlMonth_SelectedIndexChanged">
                        <asp:ListItem Text="一月" Value="1" /> ... <asp:ListItem Text="十二月" Value="12" />
                    </asp:DropDownList>
                </td>
                <td><asp:Button ID="btnTgif" runat="server" Text="TGIF (全選本月週五)" OnClick="btnTgif_Click" /></td>
            </tr>
            <tr>
                <td>起始日:</td><td><asp:TextBox ID="txtStart" runat="server" Width="40" MaxLength="2" /></td>
                <td>結束日:</td><td><asp:TextBox ID="txtEnd" runat="server" Width="40" MaxLength="2" /></td>
                <td><asp:Button ID="btnRange" runat="server" Text="選取區間" OnClick="btnRange_Click" /></td>
            </tr>
        </table>
    </form>
</body>
</html>

後端核心邏輯

using System;
using System.Web.UI.WebControls;

namespace Demo
{
    public partial class CalendarDemo : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                calMain.VisibleDate = calMain.TodaysDate;
                ddlMonth.SelectedIndex = calMain.VisibleDate.Month - 1;
            }
            UpdateLabels();
        }

        // 1. 使用者點選日期觸發
        protected void calMain_SelectionChanged(object sender, EventArgs e)
        {
            UpdateLabels();
        }

        // 2. 下拉選單切換月份
        protected void ddlMonth_SelectedIndexChanged(object sender, EventArgs e)
        {
            calMain.SelectedDates.Clear();
            int year = calMain.VisibleDate.Year;
            int month = Convert.ToInt32(ddlMonth.SelectedValue);
            calMain.VisibleDate = new DateTime(year, month, 1);
            UpdateLabels();
        }

        // 3. TGIF:全選本月所有星期五
        protected void btnTgif_Click(object sender, EventArgs e)
        {
            calMain.SelectedDates.Clear();
            int year = calMain.VisibleDate.Year;
            int month = calMain.VisibleDate.Month;
            int days = DateTime.DaysInMonth(year, month);

            for (int d = 1; d <= days; d++)
            {
                DateTime dt = new DateTime(year, month, d);
                if (dt.DayOfWeek == DayOfWeek.Friday)
                    calMain.SelectedDates.Add(dt);
            }
            UpdateLabels();
        }

        // 4. 區間選取
        protected void btnRange_Click(object sender, EventArgs e)
        {
            if (int.TryParse(txtStart.Text, out int start) && int.TryParse(txtEnd.Text, out int end))
            {
                int year = calMain.VisibleDate.Year;
                int month = calMain.VisibleDate.Month;
                DateTime dtStart = new DateTime(year, month, start);
                DateTime dtEnd = new DateTime(year, month, end);

                if (dtStart > dtEnd) { /* 提示錯誤 */ return; }

                calMain.SelectedDates.Clear();
                calMain.SelectedDates.SelectRange(dtStart, dtEnd);
                UpdateLabels();
            }
        }

        // 5. 更新標籤顯示
        private void UpdateLabels()
        {
            lblToday.Text = $"今天:{calMain.TodaysDate:yyyy/MM/dd}";
            lblSelected.Text = calMain.SelectedDate != DateTime.MinValue 
                ? $"單一選取:{calMain.SelectedDate:yyyy/MM/dd}" 
                : "單一選取:(無)";
            lblCount.Text = $"多重選取天數:{calMain.SelectedDates.Count}";
        }

        // 6. DayRender:自訂單元格樣式(如標示假日、特定業務邏輯)
        protected void calMain_DayRender(object sender, DayRenderEventArgs e)
        {
            // 週末底色
            if (e.Day.IsWeekend)
                e.Cell.BackColor = System.Drawing.ColorTranslator.FromHtml("#FFF8F0");

            // 非本月日期灰字
            if (e.Day.IsOtherMonth)
                e.Cell.ForeColor = System.Drawing.Color.LightGray;

            // 範例:特定日期加圖示/Tooltip
            if (e.Day.Date == new DateTime(2024, 10, 10))
            {
                e.Cell.Controls.Add(new LiteralControl("
雙十國慶")); e.Cell.ToolTip = "國慶日"; } } // 7. 月份切換事件(可用於載入該月行事曆資料) protected void calMain_VisibleMonthChanged(object sender, MonthChangedEventArgs e) { // 比較 e.NewDate 與 e.PreviousDate 判斷方向 // 可在此呼叫 DAL 取得該月行程,存入 Session/ViewState 供 DayRender 使用 } } }

進階技巧與常見需求

限制可選日期範圍(如:不可選過去日期)

protected void calMain_DayRender(object sender, DayRenderEventArgs e)
{
    if (e.Day.Date < DateTime.Today)
    {
        e.Day.IsSelectable = false; // 禁用選取
        e.Cell.ForeColor = System.Drawing.Color.Gray;
        e.Cell.ToolTip = "不可選擇過去日期";
    }
}

資料庫驅動行事曆(標示有事件的日期)

// Page_Load 或 VisibleMonthChanged 取得該月事件日期
HashSet eventDates = GetEventDates(calMain.VisibleDate.Year, calMain.VisibleDate.Month);

protected void calMain_DayRender(object sender, DayRenderEventArgs e)
{
    if (eventDates.Contains(e.Day.Date))
    {
        e.Cell.BackColor = System.Drawing.Color.LightBlue;
        e.Cell.ToolTip = "有行程";
        e.Cell.Controls.Add(new LiteralControl("
")); } }

無障礙與行動裝置優化

  • Calendar 渲染為 <table>,行動裝置橫向滾動體驗較差。建議改用 Flatpickr、DateRangePicker、Bootstrap Datepicker 等 JS 元件,後端僅提供 API。
  • 若必須用 Calendar,可加 CSS table { display: block; overflow-x: auto; } 強制可捲動。

總結

Calendar 控制項適合「後台管理、簡易行事曆、日期篩選器」等內部系統。核心掌握:SelectionMode、SelectedDates 集合操作(Add/Clear/SelectRange)、DayRender 客製化單元格、VisibleMonthChanged 載入月份資料。現代專案前端日期選取建議改用 JS 元件,後端僅驗證與儲存。

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