行事曆檢視表

行事曆檢視可讓使用者檢視行事曆,並與可以依月份、年份或十年瀏覽的行事曆互動。 使用者可以選取單一日期或日期範圍。 它沒有選擇器介面,而且行事曆一律為可見。

這是正確的控制項嗎?

使用行事曆檢視讓使用者從始終可見的行事曆中選擇單一日期或日期範圍。

如果您需要讓使用者一次選取多個日期,則必須使用行事曆檢視。 如果您需要讓使用者只挑選單一日期,而且不需要一律顯示行事曆,請考慮使用行事曆日期選擇器日期選擇器控制項。

如需如何選擇正確文字控制項的詳細資訊,請參閱日期和時間控制項文章。

範例

行事歷檢視是由 3 個不同的檢視所組成:月檢視、年檢視和十年檢視。 根據預設,它會從開啟月份檢視開始。 您可以藉由設定 DisplayMode 屬性來指定啟動檢視。

The 3 views of a calendar view

使用者點選月檢視中的標題可開啟年檢視,點選年檢視中的標題可開啟十年檢視。 使用者在十年檢視中挑選一年以返回年份檢視,並在年份檢視中挑選一個月以返回月份檢視。 標題一側的兩個箭頭可按月、年或十年向前或向後瀏覽。

UWP 和 WinUI 2

重要

本文中的資訊和範例針對使用 Windows App SDKWinUI 3 的應用程式進行了最佳化,但通常適用於使用 WinUI 2 的 UWP 應用程式。 如需平台特定資訊和範例,請參閱 UWP API 參考。

本節包含您在 UWP 或 WinUI 2 應用程式中使用控制項所需的資訊。

此控制項的 API 位在 Windows.UI.Xaml.Controls 命名空間中。

建議使用最新的 WinUI 2 來取得所有控制項的最新樣式和範本。 WinUI 2.2 或更新版本包含此使用圓角之控制項的新範本。 如需詳細資訊,請參閱圓角半徑

建立行事曆檢視

WinUI 3 資源庫應用程式包含大多數 WinUI 3 控制項和功能的互動式範例。 從 Microsoft Store 取得應用程式,或在 GitHub 上取得原始程式碼

此範例示範如何建立簡單的行事曆檢視。

<CalendarView/>

產生的行事曆檢視如下所示:

Example of calendar view

選取日期

根據預設,SelectionMode 屬性是設定為 Single。 這可讓使用者在行事曆中挑選單一日期。 將 SelectionMode 設定為 None 以停用日期選取。

將 SelectionMode 設定為 Multiple,讓使用者選取多個日期。 您可以將 DateTime/DateTimeOffset 物件新增至 SelectedDates集合,以選取多個日期,如下所示︰

calendarView1.SelectedDates.Add(DateTimeOffset.Now);
calendarView1.SelectedDates.Add(new DateTime(1977, 1, 5));

使用者可以按下或點選行事曆方格中的日期,以取消選取的日期。

您可以處理 SelectedDatesChanged 事件,以在 SelectedDates 集合變更時收到通知。

注意

注意如需有關日期值的重要資訊,請參閱日期和時間控制項文章中的 DateTime 與 Calendar 值

自訂行事曆檢視的外觀

行事曆檢視是由 ControlTemplate 中定義的 XAML 元素和控制項直接轉譯的視覺元素所組成。

  • 控制項範本中定義的 XAML 元素包括框線,其會括住控制項、標頭、上一個和下一個按鈕,以及 DayOfWeek 元素。 您可以設定這些元素的樣式並重新範本,就像任何 XAML 控制件一樣。
  • 行事曆方格是由 CalendarViewDayItem 物件所組成。 您無法設定這些元素的樣式或重新套用範本,但我們提供不同的屬性,讓您可以自訂它們的外觀。

此圖表顯示組成行事曆月份檢視的專案。 如需詳細資訊,請參閱 CalendarViewDayItem 類別的。

The elements of a calendar month view

下表列出您可以變更的屬性,以修改行事曆項目的外觀。

Element 屬性
DayOfWeek DayOfWeekFormat
CalendarItem CalendarItemBackgroundCalendarItemBorderBrushCalendarItemBorderThicknessCalendarItemForeground
DayItem DayItemFontFamilyDayItemFontSizeDayItemFontStyleDayItemFontWeightHorizontalDayItemAlignmentVerticalDayItemAlignmentCalendarViewDayItemStyle
MonthYearItem (在年份和十年檢視中,相當於 DayItem) MonthYearItemFontFamilyMonthYearItemFontSizeMonthYearItemFontStyleMonthYearItemFontWeight
FirstOfMonthLabel FirstOfMonthLabelFontFamilyFirstOfMonthLabelFontSizeFirstOfMonthLabelFontStyleFirstOfMonthLabelFontWeightHorizontalFirstOfMonthLabelAlignmentVerticalFirstOfMonthLabelAlignmentIsGroupLabelVisible
FirstofYearDecadeLabel (在年份和十年檢視中,相當於 FirstOfMonthLabel) FirstOfYearDecadeLabelFontFamilyFirstOfYearDecadeLabelFontSizeFirstOfYearDecadeLabelFontStyleFirstOfYearDecadeLabelFontWeight
視覺狀態框線 FocusBorderBrushHoverBorderBrushPressedBorderBrushSelectedBorderBrushSelectedForegroundSelectedHoverBorderBrushSelectedPressedBorderBrush
OutofScope IsOutOfScopeEnabledOutOfScopeBackgroundOutOfScopeForeground
Today IsTodayHighlightedTodayFontWeightTodayForeground

根據預設,月份檢視會一次顯示 6 週。 您可以藉由設定 NumberOfWeeksInView 屬性來變更顯示的週數。 顯示的最少週數為 2;最大值為 8。

根據預設,年份和十年檢視會顯示在 4x4 方格中。 若要變更行數或列數,請使用所需的行數和列數呼叫 SetYearDecadeDisplayDimensions。 這會變更年份和十年檢視的網格線。

在這裡,年份和十年檢視會設定為在 3x4 方格中顯示。

calendarView1.SetYearDecadeDisplayDimensions(3, 4);

根據預設,行事曆檢視中顯示的最小日期是目前日期之前的 100 年,而顯示的最大日期是目前日期的 100 年。 您可以藉由設定 MinDateMaxDate 屬性來變更行事曆顯示的最小和最大日期。

calendarView1.MinDate = new DateTime(2000, 1, 1);
calendarView1.MaxDate = new DateTime(2099, 12, 31);

更新行事曆日專案

行事曆中的每一天都會以 CalendarViewDayItem 物件表示。 若要存取個別的日期專案並使用其屬性和方法,請處理 CalendarViewDayItemChanging 事件,並使用事件自變數的 Item 屬性來存取 CalendarViewDayItem。

您可以將 CalendarViewDayItem.IsBlackout 屬性設定為 true,以將行事曆中的某一個日期設定為無法選取。

您可以呼叫 CalendarViewDayItem.SetDensityColors 方法來顯示一天中事件密度的相關內容資訊。 您可以每天顯示 0 到 10 個密度列,並設定每個橫條的色彩。

以下是行事曆中的一些日期專案。 第 1 天和 2 天被封鎖。第 2 天、3 天和第 4 天具有各種密度橫條集。

Calendar days with density bars

階段式轉譯

行事歷檢視可以包含大量的 CalendarViewDayItem 物件。 若要讓 UI 保持回應,並啟用行事曆的順暢導覽,行事曆檢視支援分階段轉譯。 這可讓您將一天項目的處理分成階段。 如果在完成所有階段之前將一天移出檢視,則不會再使用任何時間嘗試處理和轉譯該專案。

此範例顯示排程約會的行事歷檢視分階段轉譯。

  • 在階段 0 中,會轉譯預設的日期專案。
  • 在階段 1 中,您封鎖無法預訂的日期。 這包括已完整預訂的過去日期、星期日和日期。
  • 在階段 2 中,您會檢查當天預訂的每個約會。 您為每個已確認的約會顯示綠色密度條,為每個暫定約會顯示藍色密度條。

此範例中的 Bookings 類別來自虛構的約會預約應用程式,而且不會顯示。

<CalendarView CalendarViewDayItemChanging="CalendarView_CalendarViewDayItemChanging"/>
private void CalendarView_CalendarViewDayItemChanging(CalendarView sender,
                                   CalendarViewDayItemChangingEventArgs args)
{
    // Render basic day items.
    if (args.Phase == 0)
    {
        // Register callback for next phase.
        args.RegisterUpdateCallback(CalendarView_CalendarViewDayItemChanging);
    }
    // Set blackout dates.
    else if (args.Phase == 1)
    {
        // Blackout dates in the past, Sundays, and dates that are fully booked.
        if (args.Item.Date < DateTimeOffset.Now ||
            args.Item.Date.DayOfWeek == DayOfWeek.Sunday ||
            Bookings.HasOpenings(args.Item.Date) == false)
        {
            args.Item.IsBlackout = true;
        }
        // Register callback for next phase.
        args.RegisterUpdateCallback(CalendarView_CalendarViewDayItemChanging);
    }
    // Set density bars.
    else if (args.Phase == 2)
    {
        // Avoid unnecessary processing.
        // You don't need to set bars on past dates or Sundays.
        if (args.Item.Date > DateTimeOffset.Now &&
            args.Item.Date.DayOfWeek != DayOfWeek.Sunday)
        {
            // Get bookings for the date being rendered.
            var currentBookings = Bookings.GetBookings(args.Item.Date);

            List<Color> densityColors = new List<Color>();
            // Set a density bar color for each of the days bookings.
            // It's assumed that there can't be more than 10 bookings in a day. Otherwise,
            // further processing is needed to fit within the max of 10 density bars.
            foreach (booking in currentBookings)
            {
                if (booking.IsConfirmed == true)
                {
                    densityColors.Add(Colors.Green);
                }
                else
                {
                    densityColors.Add(Colors.Blue);
                }
            }
            args.Item.SetDensityColors(densityColors);
        }
    }
}

取得範例程式碼