Exibição de calendário

Uma exibição de calendário permite que um usuário visualize e interaja com um calendário em que ele pode navegar por mês, ano ou década. Um usuário pode selecionar uma única data ou um intervalo de datas. Ele não tem uma superfície de seletor e o calendário está sempre visível.

Esse é o controle correto?

Use um modo de exibição de calendário para permitir que um usuário selecione uma única data ou um intervalo de datas de um calendário sempre visível.

Se precisar permitir que um usuário selecione várias datas ao mesmo tempo, você deve usar um modo de exibição de calendário. Se você precisar permitir que um usuário selecione apenas uma única data e não precisar de um calendário sempre visível, considere usar um seletor de data do calendário ou um controle seletor de data.

Para obter mais informações sobre como escolher o controle correto, consulte o artigo Controles de data e hora.

Exemplos

A exibição de calendário é composta de três visões separadas: a visão de mês, a visão de ano e a visão de década. Por padrão, ele abre com o modo de exibição de mês. Você pode especificar um modo de exibição de inicialização definindo a propriedade DisplayMode.

Os três modos de exibição de um modo de exibição de calendário

Os usuários clicam no cabeçalho na exibição de mês para abrir o modo de exibição de ano, e clicam no cabeçalho na exibição de ano para abrir o modo de exibição de década. Os usuários escolhem um ano na exibição de década para retornar à exibição de ano, e escolhem um mês na exibição de ano para retornar ao modo de exibição de mês. As duas setas ao lado do cabeçalho navegam para frente ou para trás por mês, ano ou década.

UWP e WinUI 2

Importante

As informações e exemplos neste artigo são otimizados para aplicativos que usam o SDK do Aplicativo Windows e o WinUI 3, mas geralmente são aplicáveis a aplicativos UWP que usam o WinUI 2. Consulte a referência da API da UWP para obter informações e exemplos específicos da plataforma.

Esta seção contém informações necessárias para usar o controle em um aplicativo UWP ou WinUI 2.

As APIs para esse controle existem no namespace Windows.UI.Xaml.Controls .

Recomendamos usar o WinUI 2 mais recente para obter os estilos e modelos mais atuais para todos os controles. O WinUI 2.2 ou posterior inclui um novo modelo para esse controle que usa cantos arredondados. Para obter mais informações, confira Raio de canto.

Criar um modo de exibição de calendário

O aplicativo Galeria da WinUI 3 inclui exemplos interativos da maioria dos controles, recursos e funcionalidades da WinUI 3. Obtenha o aplicativo na Microsoft Store ou o código-fonte no GitHub

Este exemplo mostra como criar um modo de exibição de calendário simples.

<CalendarView/>

O modo de exibição de calendário resultante fica assim:

Exemplo de exibição de calendário

Selecionando datas

Por padrão, a propriedade SelectionMode é definida como Single. Isso permite que um usuário escolha uma única data no calendário. Defina SelectionMode como Nenhum para desabilitar a seleção de data.

Defina SelectionMode como Múltiplo para permitir que um usuário selecione várias datas. Você pode selecionar várias datas programaticamente, adicionando objetos DateTime/DateTimeOffset à coleção SelectedDates, conforme mostrado aqui:

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

Um usuário poderá desmarcar uma data selecionada, clicando ou tocando nela na grade do calendário.

Você pode manipular o evento SelectedDatesChanged para ser notificado quando a coleção SelectedDates for alterada.

Observação

Para obter informações importantes sobre valores de data, consulte Valores DateTime e Calendar no artigo Controles de data e hora.

Personalizando a aparência do modo de exibição de calendário

O modo de exibição de calendário é composto de elementos XAML definidos em ControlTemplate e elementos visuais renderizados diretamente pelo controle.

  • Os elementos XAML definidos no modelo de controle incluem a borda que envolve o controle, o cabeçalho, os botões Anterior e Próximo e elementos DayOfWeek. Você pode definir o estilo e o novo modelo desses elementos como qualquer controle XAML.
  • A grade de calendário é composta de objetos CalendarViewDayItem. Não é possível definir o estilo ou o novo modelo desses elementos, mas são fornecidas várias propriedades para permitir que você personalize a aparência deles.

Este diagrama mostra os elementos que compõem o modo de exibição de mês do calendário. Para obter mais informações, confira os Comentários sobre a classe CalendarViewDayItem.

Os elementos de um modo de exibição de mês de calendário

Esta tabela lista as propriedades que você pode alterar para modificar a aparência de elementos de calendário.

Elemento Propriedades
DayOfWeek DayOfWeekFormat
CalendarItem CalendarItemBackground, CalendarItemBorderBrush, CalendarItemBorderThickness, CalendarItemForeground
DayItem DayItemFontFamily, DayItemFontSize, DayItemFontStyle, DayItemFontWeight, HorizontalDayItemAlignment, VerticalDayItemAlignment, CalendarViewDayItemStyle
MonthYearItem (nos modos de exibição de ano e de década, equivalentes a DayItem) MonthYearItemFontFamily, MonthYearItemFontSize, MonthYearItemFontStyle, MonthYearItemFontWeight
FirstOfMonthLabel FirstOfMonthLabelFontFamily, FirstOfMonthLabelFontSize, FirstOfMonthLabelFontStyle, FirstOfMonthLabelFontWeight, HorizontalFirstOfMonthLabelAlignment, VerticalFirstOfMonthLabelAlignment, IsGroupLabelVisible
FirstofYearDecadeLabel (nos modos de exibição de ano e de década, equivalentes a FirstOfMonthLabel) FirstOfYearDecadeLabelFontFamily, FirstOfYearDecadeLabelFontSize, FirstOfYearDecadeLabelFontStyle, FirstOfYearDecadeLabelFontWeight
Bordas de Estado Visual FocusBorderBrush, HoverBorderBrush, PressedBorderBrush, SelectedBorderBrush, SelectedForeground, SelectedHoverBorderBrush, SelectedPressedBorderBrush
OutofScope IsOutOfScopeEnabled, OutOfScopeBackground, OutOfScopeForeground
Hoje IsTodayHighlighted, TodayFontWeight, TodayForeground

Por padrão, o modo de exibição de mês mostra 6 semanas de cada vez. Você pode alterar o número de semanas mostrado, definindo a propriedade NumberOfWeeksInView. O número mínimo de semanas para mostrar é 2; o máximo, 8.

Por padrão, os modos de exibição de ano e de década aparecem em uma grade de 4 x 4. Para alterar o número de linhas ou colunas, chame SetYearDecadeDisplayDimensions com o número desejado de linhas e colunas. Isso irá alterar a grade para os modos de exibição de ano e de década.

Aqui, os modos de exibição de ano e de década são definidos para aparecer em uma grade de 3 x 4.

calendarView1.SetYearDecadeDisplayDimensions(3, 4);

Por padrão, a data mínima mostrada na exibição de calendário é 100 anos antes da data atual, e a data máxima mostrada é 100 anos após a data atual. Você pode alterar as datas mínima e máxima que o calendário mostra definindo as propriedades MinDate e MaxDate.

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

Atualizando itens de dia do calendário

Cada dia no calendário é representado por um objeto CalendarViewDayItem. Para acessar um item individual de dia e usar seus métodos e propriedades, manipule o evento CalendarViewDayItemChanging e use a propriedade Item de argumentos de evento para acessar o CalendarViewDayItem.

Você pode fazer um dia não selecionável na exibição de calendário definindo sua propriedade CalendarViewDayItem.IsBlackout como true.

Você pode mostrar informações contextuais sobre a densidade de eventos em um dia chamando o método CalendarViewDayItem.SetDensityColors. Você pode mostrar de 0 a 10 barras de densidade para cada dia, e definir a cor de cada barra.

Veja alguns itens de dia em um calendário. Dias 1 e 2 são escurecidos. Dias 2, 3 e 4 têm várias definições de barras de densidade.

Dias de calendário com barras de densidade

Renderização em fases

Um modo de exibição de calendário pode conter um grande número de objetos CalendarViewDayItem. Para manter a interface do usuário rápida e habilitar uma navegação suave pelo calendário, o modo de exibição de calendário suporta renderização em fases. Essa função permite que você separe o processamento de um item de dia em fases. Se um dia for movido para fora da exibição antes que todas as fases sejam concluídas, não será usado mais tempo para processar e renderizar aquele item.

Este exemplo mostra a renderização em fases de uma exibição de calendário para agendar compromissos.

  • Na fase 0, o item dia padrão é renderizado.
  • Na fase 1, você escurece datas que não podem ser registradas. Isso inclui datas passadas, domingos e datas que já estão totalmente reservadas.
  • Na fase 2, você verifica cada compromisso que está reservado para o dia. Você exibe uma barra de densidade verde para cada compromisso confirmado e uma barra de densidade azul para cada compromisso provisório.

A classe Bookings neste exemplo é de um aplicativo de reserva de compromisso fictício, e não é exibida.

<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);
        }
    }
}

Obter o código de exemplo