quinta-feira, 2 de junho de 2011

WPF Calendar com BoldedDates

O controle Calendar do WPF é muito parecido com o MonthCalendar do WindowsForms. Porém como muito se acontece no WPF você tem que abrir a cabeça quando quer adicionar uma funcionalidade mesmo que ela fosse muito fácil no WindowsForms. Isso se deve ao fato do WPF possui seus controles muito mais poderosos, porém poder não quer dizer mais simples de ser utilizado.
Para fazer a mesma funcionalidade do BoldedDates do MonthCalendar você tem que trabalhar com CalendarDayButtonStyle em conjunto com o IValueConverter.
Caso você ja saiba as datas que devem ficar bold, você pode fazer da seguinte maneira:

1) Declare seu convert:

namespace WPFBoldDates
{
      public class BoldDateConverter : IValueConverter
     {
             public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                    if(System.Convert.ToDateTime(value) == new DateTime(2011, 06, 06))
                    {
                             return FontWeights.Bold;
                    }
                    return FontWeights.Normal;
             }

              public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
             {
                       return value;
             }
      }
}
 
2) Configura o style:
 
<Window x:Class="WpfApplication1.MainWindow"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:my="clr-namespace:WPFBoldDates"
                Title="MainWindow" Height="350" Width="525">
      <Window.Resources>
           <my:BoldDateConverter x:Key="boldConverter" />
      </Window.Resources>
      <Grid>
            <Calendar x:Name="calendario">
                  <Calendar.CalendarDayButtonStyle>
                    <Style TargetType="CalendarDayButton">
            <Setter Property="FontWeight" Value="{Binding Converter={StaticResource boldConverter}}" />
                    </Style>
                  </Calendar.CalendarDayButtonStyle>
            </Calendar>
     </Grid>
</Window>

Pronto, o dia 06/06/2011 ficará em negrito.

Caso queira trabalhar com datas dinâmicas você pode utilizar um CollectionViewSource.

1) Adicione um recurso para seu Window do tipo CollectionViewSource e passe ela como parâmetro do seu binding:

<Window x:Class="WpfApplication1.MainWindow"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:my="clr-namespace:WPFBoldDates"
                Title="MainWindow" Height="350" Width="525">
      <Window.Resources>
           <my:BoldDateConverter x:Key="boldConverter" />
           <CollectionViewSource x:Key="dates" />
      </Window.Resources>
      <Grid>
            <Calendar x:Name="calendario">
                  <Calendar.CalendarDayButtonStyle>
                    <Style TargetType="CalendarDayButton">
            <Setter Property="FontWeight" Value="{Binding Converter={StaticResource boldConverter}, ConverterParameter={StaticResource dates}}" />
                    </Style>
                  </Calendar.CalendarDayButtonStyle>
            </Calendar>
     </Grid>
</Window>

2) No construtor do seu Window inicialize o CollectionViewSource:

public partial class MainWindow : Window
{
       public MainWindow()
      {
             InitializeComponent();
             List<DateTime> dates = new List<DateTime>();
             // Só para demonstração, você pode optar por ir no banco de dados
             dates.Add(new DateTime(2011, 6, 6));
            CollectionViewSource source = FindResource("dates") as CollectionViewSource;
            source.Source = dates;
       }
}
 
3) Para finalizar ajuste seu IValueConverter:
 
      public class BoldDateConverter : IValueConverter
     {
             public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                    List<DateTime> dates = (parameter as CollectionViewSource).Source as List<DateTime>;
                    if(dates.Contains(System.Convert.ToDateTime(value)))
                          return FontWeights.Bold;

                    return FontWeights.Normal;
             }

              public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
             {
                       return value;
             }
      }
}

Como você pode ver, um tanto grande nosso esforço, porém não se limite apenas a usar o bold. Com style vocde formatar seu botão completamente para que ele atenda suas necessidades.

Até a próxima.

Nenhum comentário:

Postar um comentário