Exibição de calendário

Um modo de exibição de calendário permite que um usuário exiba e interaja com um calendário no qual 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 escolha uma única data ou um intervalo de datas em um calendário sempre visível.

Se você precisar permitir que um usuário selecione várias datas ao mesmo tempo, deverá 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 visualização do calendário é composta por 3 visualizações separadas: a visualização do mês, a visualização do ano e a visualização da década. Por padrão, ele começa com a visualização do mês aberta. Você pode especificar um modo de exibição de inicialização definindo a propriedade DisplayMode.

As 3 visualizações de uma visualização de calendário

Os usuários clicam no cabeçalho no modo de exibição de mês para abrir o modo de exibição de ano e clicam no cabeçalho no modo de 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 à 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 de 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.

É recomendável usar a WinUI 2 mais recente para obter os estilos e modelos mais atuais para todos os controles. 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/>

A visualização de calendário resultante tem esta aparência:

Exemplo de visualizaçã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 None para desabilitar a seleção de data.

Defina SelectionMode como Multiple 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 pode 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 de DateTime e Calendar no artigo Controles de data e hora.

Personalizando a aparência da visualização de calendário

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

  • Os elementos XAML definidos no modelo de controle incluem a borda que inclui o controle, o cabeçalho, os botões anterior e seguinte e os elementos DayOfWeek. Você pode estilizar e remodelar esses 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 a exibição mensal do calendário. Para obter mais informações, confira os Comentários sobre a classe CalendarViewDayItem.

Os elementos de uma exibição de mês do calendário

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

Element Propriedades
DayOfWeek DayOfWeekFormat
CalendarItem CalendarItemBackground, CalendarItemBorderBrush, CalendarItemBorderThickness, CalendarItemForeground
Item do dia DayItemFontFamily, DayItemFontSize, DayItemFontStyle, DayItemFontWeight, HorizontalDayItemAlignment, VerticalDayItemAlignment, CalendarViewDayItemStyle
MonthYearItem (nas exibições de ano e década, equivalente a DayItem) MonthYearItemFontFamily, MonthYearItemFontSize, MonthYearItemFontStyle, MonthYearItemFontWeight
Primeiro do MêsRótulo FirstOfMonthLabelFontFamily, FirstOfMonthLabelFontSize, FirstOfMonthLabelFontStyle, FirstOfMonthLabelFontWeight, HorizontalFirstOfMonthLabelAlignment, VerticalFirstOfMonthLabelAlignment, IsGroupLabelVisible
FirstofYearDecadeLabel (nas exibições de ano e década, equivalente a FirstOfMonthLabel) FirstOfYearDecadeLabelFontFamily, FirstOfYearDecadeLabelFontSize, FirstOfYearDecadeLabelFontStyle, FirstOfYearDecadeLabelFontWeight
Bordas de estado visual FocusBorderBrush, HoverBorderBrush, PressedBorderBrush, SelectedBorderBrush, SelectedForeground, SelectedHoverBorderBrush, SelectedPressedBorderBrush
Fora do escopo IsOutOfScopeEnabled, OutOfScopeBackground, OutOfScopeForeground
Hoje IsTodayHighlighted, TodayFontWeight, TodayForeground

Por padrão, a exibição do mês mostra 6 semanas por 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, as exibições de ano e década são exibidas em uma grade 4x4. Para alterar o número de linhas ou colunas, chame SetYearDecadeDisplayDimensions com o número desejado de linhas e colunas. Isso mudará a grade para as visualizações de ano e década.

Aqui, as visualizações de ano e década são definidas para serem exibidas em uma grade 3x4.

calendarView1.SetYearDecadeDisplayDimensions(3, 4);

Por padrão, a data mínima mostrada no modo de 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 do 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.

Aqui estão alguns itens do dia em um calendário. Os dias 1 e 2 são apagados. Os dias 2, 3 e 4 têm várias barras de densidade definidas.

Dias corridos 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 responsiva e permitir uma navegação suave pelo calendário, o modo de exibição de calendário dá suporte à renderização em fases. Isso permite dividir o processamento de um item do dia em fases. Se um dia for movido para fora da exibição antes que todas as fases sejam concluídas, não será mais usado tempo tentando processar e renderizar esse item.

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

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

A Bookings classe neste exemplo é de um aplicativo de agendamento de compromissos fictício e não é mostrada.

<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