予定表ビュー

予定表ビューを使用すると、ユーザーは月、年、または 10 年ごとに移動できる予定表を表示および操作できます。 ユーザーは、1 つの日付または日付の範囲を選択できます。 ピッカーの表面がなく、カレンダーは常に表示されています。

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

予定表ビューを使用して、ユーザーが常に表示される予定表から 1 つの日付または日付の範囲を選択できるようにします。

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

適切なコントロールの選択の詳細については、 日付と時刻コントロール に関する記事を参照してください。

例示

カレンダー ビューは、月ビュー、年ビュー、10 年ビューの 3 つの独立したビューで構成されています。 既定では、月ビューが開いた状態で開始されます。 スタートアップ ビューを指定するには、 DisplayMode プロパティを設定します。

カレンダービューの3つの表示形式

ユーザーは月ビューでヘッダーをクリックして年ビューを開き、年ビューでヘッダーをクリックして 10 年ビューを開きます。 ユーザーは 10 年ビューで年を選択して年ビューに戻り、年ビューで月を選択して月ビューに戻ります。 ヘッダーの横にある 2 つの矢印は、月、年、または 10 年ごとに前後に移動します。

予定表ビューを作成する

WinUI 3 ギャラリー アイコン WinUI 3 ギャラリー アプリには、WinUI コントロールと機能の対話型の例が含まれています。 Microsoft Store からアプリを取得するか、GitHub でソース コードを参照します。

この例では、単純な予定表ビューを作成する方法を示します。

<CalendarView/>

結果の予定表ビューは次のようになります。

予定表ビューの例

日付の選択

既定では、 SelectionMode プロパティは Single に設定されます。 これにより、ユーザーは予定表で 1 つの日付を選択できます。 日付の選択を無効にするには、SelectionMode を None に設定します。

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

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

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

SelectedDatesChangedSelectedDates コレクションが変更されたときに通知されるイベントを処理できます。

注

日付の値に関する重要な情報については、日付と時刻コントロールの記事の DateTime と Calendar の値 を参照してください。

予定表ビューの外観のカスタマイズ

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

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

この図は、カレンダーの月ビューを構成する要素を示しています。 詳細については、 CalendarViewDayItem クラスの解説を参照してください。

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

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

要素 プロパティ
DayOfWeek DayOfWeekFormat (週の日形式)
カレンダーアイテム CalendarItemBackground、 CalendarItemBorderBrush、 CalendarItemBorderThickness、 CalendarItemForeground
デイアイテム DayItemFontFamily、 DayItemFontSize、 DayItemFontStyle、 DayItemFontWeight、 HorizontalDayItemAlignment、 VerticalDayItemAlignment、 CalendarViewDayItemStyle
MonthYearItem (年ビューと 10 年ビューで、DayItem に相当) MonthYearItemFontFamily、 MonthYearItemFontSize、 MonthYearItemFontStyle、 MonthYearItemFontWeight
FirstOfMonthLabel FirstOfMonthLabelFontFamily, FirstOfMonthLabelFontSize、 FirstOfMonthLabelFontStyle、 FirstOfMonthLabelFontWeight、 HorizontalFirstOfMonthLabelAlignment、 VerticalFirstOfMonthLabelAlignment、 IsGroupLabelVisible
FirstofYearDecadeLabel (年ビューと 10 年ビューで、FirstOfMonthLabel に相当) FirstOfYearDecadeLabelFontFamily、 FirstOfYearDecadeLabelFontSize、 FirstOfYearDecadeLabelFontStyle、 FirstOfYearDecadeLabelFontWeight
視覚的な状態境界 FocusBorderBrush、 HoverBorderBrush、 PressedBorderBrush、 SelectedBorderBrush、 SelectedForeground、 SelectedHoverBorderBrush、 SelectedPressedBorderBrush
OutofScope IsOutOfScopeEnabled、 OutOfScopeBackground、 OutOfScopeForeground
今日 IsTodayHighlighted、 TodayFontWeight、 TodayForeground

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

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

ここでは、年ビューと 10 年ビューが 3 x 4 グリッドで表示されるように設定されています。

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 メソッドを呼び出すことで、1 日のイベントの密度に関するコンテキスト情報を表示できます。 日ごとに 0 から 10 個の密度バーを表示し、各バーの色を設定できます。

カレンダーの日項目を次に示します。 1 日目と 2 日目は黒く表示されます。日 2、3、4 には、さまざまな密度バーが設定されています。

密度バーを含むカレンダーの日数

段階的なレンダリング

予定表ビューには、多数の CalendarViewDayItem オブジェクトを含めることができます。 UI の応答性を維持し、予定表をスムーズにナビゲーションできるようにするために、カレンダー ビューでは段階的なレンダリングがサポートされています。 これにより、日項目の処理をフェーズに分割できます。 すべてのフェーズが完了する前に 1 日がビュー外に移動された場合、その項目の処理とレンダリングに時間は使用されません。

この例では、予定をスケジュールするための予定表ビューの段階的なレンダリングを示します。

  • フェーズ 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);
        }
    }
}