カレンダー ビュー

カレンダー ビューを使うと、ユーザーはカレンダーを表示し操作できます (カレンダーは、月、年、または 10 年単位で操作できます)。 ユーザーは 1 つの日付や日付の範囲を選ぶことができます。 カレンダー ビューには選択コントロール サーフェイスがなく、カレンダーは常に表示されます。

これは適切なコントロールですか?

カレンダー ビューを使うと、ユーザーは常に表示されているカレンダーから 1 つの日付または日付の範囲を選ぶことができます。

ユーザーが一度に複数の日付を選べるようにする必要がある場合は、カレンダー ビューを使う必要があります。 ユーザーが 1 つの日付しか選べないようにする必要があり、カレンダーを常に表示する必要がない場合は、カレンダーの日付の選択コントロールまたは日付の選択コントロールを使うことを検討してください。

適切なコントロールの選択について詳しくは、「日付と時刻コントロール」をご覧ください。

カレンダー ビューは、月ビュー、年ビュー、10 年ビューという 3 つの個別のビューで構成されています。 既定では、月ビューが開きます。 スタートアップ表示を指定するには、DisplayMode プロパティを設定します。

カレンダー ビューの 3 つのビュー

ユーザーが月ビューのヘッダーをクリックすると年ビューが開き、年ビューのヘッダーをクリックすると 10 年ビューが開きます。 また、10 年ビューで年を選ぶと年ビューに戻り、年ビューで月を選ぶと月ビューに戻ります。 ヘッダーの横にある 2 つの矢印を使うと、月、年、10 年単位で前後に移動できます。

UWP と WinUI 2

重要

この記事の情報と例は、Windows アプリ 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 でソース コードを取得します。

次の例は、1 つのカレンダー ビューを作成する方法を示しています。

<CalendarView/>

結果のカレンダー ビューは次のように表示されます。

カレンダー ビューの例

日付の選択

既定では、SelectionMode プロパティは Single に設定されています。 このため、ユーザーはカレンダー内の 1 つの日付を選ぶことができます。 日付の選択を無効にするには、SelectionMode を None に設定します。

ユーザーが複数の日付を選べるようにするには、SelectionMode を Multiple に設定します。 次のように SelectedDates コレクションに DateTime/DateTimeOffset オブジェクトを追加すると、プログラムから複数の日付を選ぶことができます。

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

ユーザーは、選択済みの日付をカレンダー グリッドでクリックまたはタップすると、その日付の選択を解除できます。

SelectedDates コレクションが変化したときに通知を受け取るようにするには、SelectedDatesChanged イベントを処理します。

注意

日付値の重要な情報については、「日付と時刻コントロール」の「DateTime と Calendar の値」をご覧ください。

カレンダー ビューの外観のカスタマイズ

カレンダー ビューは、ControlTemplate で定義される XAML 要素と、コントロールによって直接レンダリングされるビジュアル要素で構成されます。

  • コントロール テンプレートで定義される XAML 要素には、コントロールを囲む境界線、ヘッダー、[前へ] ボタンと [次へ] ボタン、および DayOfWeek 要素が含まれています。 すべての XAML コントロールと同様、これらの要素にスタイルを指定し、テンプレートを再適用することができます。
  • カレンダー グリッドは、CalendarViewDayItem オブジェクトで構成されています。 これらの要素のスタイルを指定したり、テンプレートを再適用することはできませんが、それらの外観をカスタマイズできるさまざまなプロパティが用意されています。

次の図は、カレンダーの月ビューを構成する要素を示しています。 詳しくは、CalendarViewDayItem クラスの「解説」をご覧ください。

カレンダーの月ビューの要素

次の表は、カレンダー要素の外観を変えるために変更できるプロパティを示しています。

要素 プロパティ
DayOfWeek DayOfWeekFormat
CalendarItem CalendarItemBackgroundCalendarItemBorderBrushCalendarItemBorderThicknessCalendarItemForeground
DayItem DayItemFontFamilyDayItemFontSizeDayItemFontStyleDayItemFontWeightHorizontalDayItemAlignmentVerticalDayItemAlignmentCalendarViewDayItemStyle
MonthYearItem (年ビューと 10 年ビューに含まれていて DayItem と等価) MonthYearItemFontFamilyMonthYearItemFontSizeMonthYearItemFontStyleMonthYearItemFontWeight
FirstOfMonthLabel FirstOfMonthLabelFontFamilyFirstOfMonthLabelFontSizeFirstOfMonthLabelFontStyleFirstOfMonthLabelFontWeightHorizontalFirstOfMonthLabelAlignmentVerticalFirstOfMonthLabelAlignmentIsGroupLabelVisible
FirstofYearDecadeLabel (年ビューと 10 年ビューに含まれていて、FirstOfMonthLabel と等価) FirstOfYearDecadeLabelFontFamilyFirstOfYearDecadeLabelFontSizeFirstOfYearDecadeLabelFontStyleFirstOfYearDecadeLabelFontWeight
表示状態の境界線 FocusBorderBrushHoverBorderBrushPressedBorderBrushSelectedBorderBrushSelectedForegroundSelectedHoverBorderBrushSelectedPressedBorderBrush
OutofScope IsOutOfScopeEnabledOutOfScopeBackgroundOutOfScopeForeground
現在 IsTodayHighlightedTodayFontWeightTodayForeground

既定では、月ビューは一度に 6 週間を表示します。 表示する週数を変更するには、NumberOfWeeksInViewプロパティを設定します。 表示する週数の最小値は 2 で、最大値は 8 です。

既定では、年ビューと 10 年ビューは 4x4 のグリッドに表示されます。 行または列の数を変更するには、目的の行数と列数を指定して SetYearDecadeDisplayDimensions を呼び出します。 これにより、年ビューと 10 年ビューの両方のグリッドが変更されます。

次の例は、年ビューと 10 年ビューを 3x4 のグリッドに表示するよう設定しています。

calendarView1.SetYearDecadeDisplayDimensions(3, 4);

既定では、カレンダー ビューに表示される日付の最小値は 100 年前の現在日で、表示される日付の最大値は 100 年後の現在日です。 カレンダーに表示する最小日付と最大日付を変更するには、MinDate プロパティと MaxDate プロパティを設定します。

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 には、さまざまな密度コントロール バーが設定されています。

密度コントロール バーが設定されたカレンダーの日付

段階的なレンダリング

カレンダー ビューには、多数の 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);
        }
    }
}

サンプル コードの入手