Styling the WPF Calendar to Resemble Outlook's Month View Calendar
By Michael Detras
This article shows how to style the WPF calendar to resemble Microsoft Outlook Calendar in Month view and how to add appointments.
Introduction
I was in search for a calendar where appointments can be added. I've seen a great
CodeProject article by kirkaiya where he achieved this by creating a UserControl. It's very good but
I thought I could achieve almost the same thing by styling the WPF Calendar.
Figure 1 shows the WPF calendar.

Figure 1. WPF Calendar in its Default Style
My first impression is that it might not be possible. Anyway, I wanted to give it
shot. I came across another article at MSDN Magazine, this time by Charles Petzold. He explained in great detail the
different parts of the Calendar's template. After reading the article, it seems
to me that it is not enough to change the Calendar's template. A custom control
that inherits from Calendar should be created to support appointments.
Getting Started
The best way to style a WPF control is to start from the default style. Fortunately,
we don't need any tools to get the default style. The source code is freely available
at CodePlex, so I recommend downloading it first. Upon extracting the zip file,
you can get the Calendar's default style from WPFToolkitBinariesAndSource\Toolkit-release\Calendar\Themes\Generic.xaml.
This file has a resource dictionary containing 4 styles for the following controls:
Calendar, CalendarItem, CalendarDayButton and CalendarButton.
The Calendar's control template only consists of a CalendarItem control inside a
StackPanel. This means that the default appearance of the Calendar is mostly
defined by the CalendarItem's control template. However, you can still add other
controls to the Calendar's template.
The CalendarItem control is basically divided into the following parts: previous
button, next button, header button, month content grid, and year content grid.
The appearance of the CalendarItem depends on the selected display mode: month,
year or decade.
The month content grid is used when the display mode is month while the year content
grid is used for the other two display modes. The CalendarItem fills up the month
content grid with CalendarDayButton controls. Meanwhile, the year content grid
is filled up with CalendarButton controls. Since we are only interested in the
month view of the calendar, we don't need to edit the CalendarButton template.
Let's create a WPF application that shows a calendar in the main window. Copy the
default styles for Calendar, CalendarItem and CalendarDayButton controls in the
window's resources and add the required assemblies and namespaces. If you are
using Visual Studio 2008 and .NET 3.5 SP1, you might get the following error:
"The attachable property 'VisualStateGroups' was not found in type 'VisualStateManager'.
This is a known bug and you won't be able to see the Calendar in the WPF designer.
However, the application should be able to run without any errors.
Resizing the Calendar
The Calendar should fill the entire grid and resized when the main window is resized.
This can't be done just by setting the width and height of the Calendar. First,
let's change the Calendar's control template. I changed the StackPanel into a
Grid and removed the HorizontalAlignment.
<Grid Name="PART_Root">
<primitives:CalendarItem
Name="PART_CalendarItem"
Style="{TemplateBinding CalendarItemStyle}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
/>
</Grid>
Listing 1. Calendar Control Template
Although the CalendarItem fills the grid, the CalendarItem's content (the navigation
buttons, header button and month content grid) is aligned to the top left corner
of the grid. So we need to edit the CalendarItem's template so that the content
is distributed evenly. But first, we should give a key to the CalendarItem style
and use it as the value of the Calendar's CalendarItemStyle property. After that,
look for the grid that has 2 rows and 3 columns in the CalendarItem's control
template. The first row contains the navigation and header buttons. The second
row contains the month content grid. The first column contains the previous button,
second column contains the header button and third column contains the next column.
The month content grid spans 3 columns. Let's add another column that will occupy
the remaining space. The month content grid will now span 4 columns.
We should also change the row and column definitions of the month content grid. This
grid contains 7 rows and 7 columns, where the Height and Width properties are
set to Auto. The first row corresponds to the day title (Su, Mo, Tu, etc.) while
the other 6 rows contain the days of the month (1, 2, 3 and so on). The 7 columns
correspond to the 7 days of the week. Let's set the Height of the last 6 rows
and the Width of all columns to *. These changes result in the following figure.

Figure 2. Resized Calendar
Styling the Navigation and Header Buttons
The navigation buttons in Outlook are displayed as arrows inside circles. The displayed
month is also not in the middle of the navigation buttons, but located at the
right. The font properties are also a bit different. Let's start first with the
circle background of the navigation buttons.
<Style x:Key="NavigationEllipseStyle" TargetType="{x:Type Ellipse}">
<Setter Property="Width" Value="20"/>
<Setter Property="Height" Value="20"/>
<Setter Property="Stroke" Value="#FF8EB0DC"/>
<Setter Property="StrokeThickness" Value="1"/>
<Setter Property="Fill">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#FFFAFCFF" Offset="0"/>
<GradientStop Color="#FFFAFCFF" Offset="0.5"/>
<GradientStop Color="#FFCCE2FF" Offset="0.5"/>
<GradientStop Color="#FFCCE2FF" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
Listing 2. The Navigation Button's Ellipse
I added this style in the resources section of the grid containing the navigation
buttons. The following code shows the inner grid of the updated previous button
template which uses the style shown in Listing 2. The path objects that make
up the arrow and other properties like margin and width are also updated.
<Grid>
<Ellipse Style="{StaticResource NavigationEllipseStyle}"/>
<Path Margin="4,0,0,0" Height="10" Width="6" VerticalAlignment="Center" HorizontalAlignment="Left" Stretch="Fill" Data="M288.75,232.25 L283,236.625 L288.75,240.625" StrokeThickness="2">
<Path.Stroke>
<SolidColorBrush x:Name="TextColor" Color="#FF406CA6" />
</Path.Stroke>
</Path>
<Path Margin="4,0,0,0" Height="10" Width="12" VerticalAlignment="Center" HorizontalAlignment="Left" Stretch="Fill" Data="M283,236.625 L297,236.625" Stroke="#FF406CA6" StrokeThickness="2"/>
</Grid>
Listing 3. Part of Updated Previous Button Template
In the following code, I added a margin around the previous button and set its width
to 20 instead. I just applied the same thing with the next button, with the arrow's
paths reversed.
<Button x:Name="PART_PreviousButton"
Margin="4"
Grid.Row="0" Grid.Column="0"
Template="{StaticResource PreviousButtonTemplate}"
Height="20" Width="20"
HorizontalAlignment="Left"
Focusable="False"
/>
Listing 4. Updated Previous Button
Finally, I changed the font weight and size properties of the header button. Also
notice that the header and next buttons have switched places.
<Button x:Name="PART_HeaderButton"
Grid.Row="0" Grid.Column="2"
Template="{StaticResource HeaderButtonTemplate}"
HorizontalAlignment="Center" VerticalAlignment="Center"
FontWeight="Normal" FontSize="20"
Focusable="False"
/>
Listing 5. Updated Header Button
The following figure shows the updated Calendar.

Figure 3. Updated Navigation and Header Buttons
Changing the Day Title Format
As you see, the format of each day title is set to the shortest day name like Su
for Sunday, Mo for Monday, and so on. Unfortunately, the Calendar or the CalendarItem
does not expose any property that let's us change the day title format easily.
The CalendarItem uses only the ShortestDayNames property of the current date
format. However, we can still change the format by using an IValueConverter as
you will see later. The following code shows the updated DayTitleTemplate.
<local:DayNameConverter x:Key="DayNameConverter"/>
<!-- Start: Data template for header button -->
<DataTemplate x:Key="DayTitleTemplate">
<Grid>
<TextBlock
FontWeight="Normal"
FontFamily="Arial"
FontSize="10.5"
Foreground="#FF7C93D7"
HorizontalAlignment="Center"
Text="{Binding Converter={StaticResource DayNameConverter}}"
Margin="0,6,0,6"
VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
Listing 6. Updated Day Title Template
The Text property of the TextBlock is bound to a string representing the shortest
day name. So if we want to change Su to Sunday, Mo to Monday and so on, we need
to use an IValueConverter, like the one shown below.
/// <summary>
/// Converts the specified short day name to its normal counterpart.
/// </summary>
[ValueConversion(typeof(string), typeof(string))]
public class DayNameConverter : IValueConverter
{
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
DateTimeFormatInfo dateTimeFormat = GetCurrentDateFormat();
string[] shortestDayNames = dateTimeFormat.ShortestDayNames;
string[] dayNames = dateTimeFormat.DayNames;
for (int i = 0; i < shortestDayNames.Count(); i++)
{
if (shortestDayNames[i] == value.ToString())
{
return dayNames[i];
}
}
return null;
}
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
private static DateTimeFormatInfo GetCurrentDateFormat()
{
if (CultureInfo.CurrentCulture.Calendar is GregorianCalendar)
{
return CultureInfo.CurrentCulture.DateTimeFormat;
}
foreach (Calendar cal in CultureInfo.CurrentCulture.OptionalCalendars)
{
if (cal is GregorianCalendar)
{
DateTimeFormatInfo dtfi = new CultureInfo(CultureInfo.CurrentCulture.Name).DateTimeFormat;
dtfi.Calendar = cal;
return dtfi;
}
}
DateTimeFormatInfo dt = new CultureInfo(CultureInfo.InvariantCulture.Name).DateTimeFormat;
dt.Calendar = new GregorianCalendar();
return dt;
}
}
Listing 7. Day Name Converter
This IValueConverter converts the shortest day name to its normal day name equivalent.
The Convert method uses the GetCurrentDateFormat method in getting the current
date format. This is the same method used by the CalendarItem in generating the
day titles. The following figure shows the updated Calendar. Notice that I also
changed the text color.

Figure 4. Updated Day Titles
Styling the CalendarDayButton
In Outlook, the days are located on the top left corner of each cell. Also, there
is a filled rectangle on top of each cell. To imitate this in our Calendar, we'll
need to update the CalendarDayButton template. The following XAML code is a part
of the updated CalendarDayButton control template.
<Rectangle x:Name="SelectedBackground" Grid.Row="1" RadiusX="1" RadiusY="1" Opacity="0" Fill="{TemplateBinding Background}"/>
<Rectangle x:Name="Background" Grid.Row="1" RadiusX="1" RadiusY="1" Opacity="0" Fill="{TemplateBinding Background}" />
<Rectangle x:Name="InactiveBackground" Grid.Row="1" RadiusX="1" RadiusY="1" Opacity="0" Fill="#FFA5BFE1"/>
<Border>
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop x:Name="StartGradient" Color="#FFDFE8F5" Offset="0"/>
<GradientStop Color="{Binding ElementName=StartGradient, Path=Color}" Offset="0.5"/>
<GradientStop x:Name="EndGradient" Color="#FFC9D9ED" Offset="0.5"/>
<GradientStop Color="{Binding ElementName=EndGradient, Path=Color}" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<ContentPresenter
x:Name="NormalText"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="5,1,5,1">
<TextElement.Foreground>
<SolidColorBrush x:Name="selectedText" Color="#FF333333"/>
</TextElement.Foreground>
</ContentPresenter>
</Border>
<Rectangle x:Name="Border" StrokeThickness="0.5" Grid.RowSpan="2" SnapsToDevicePixels="True">
<Rectangle.Stroke>
<SolidColorBrush x:Name="BorderBrush" Color="#FF5D8CC9"/>
</Rectangle.Stroke>
</Rectangle>
<Path x:Name="Blackout" Grid.Row="1" Opacity="0" Margin="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RenderTransformOrigin="0.5,0.5" Fill="#FF000000" Stretch="Fill" Data="M8.1772461,11.029181 L10.433105,11.029181 L11.700684,12.801641 L12.973633,11.029181
L15.191895,11.029181 L12.844727,13.999395 L15.21875,17.060919 L12.962891,17.060919
L11.673828,15.256231 L10.352539,17.060919 L8.1396484,17.060919 L10.519043,14.042364
z"/>
<Rectangle Width="0" x:Name="DayButtonFocusVisual" Grid.Row="1" Visibility="Collapsed" IsHitTestVisible="false" RadiusX="1" RadiusY="1" Stroke="#FF45D6FA"/>
Listing 8. Part of Updated CalendarDayButton Template
If you look at the default style, there is a Rectangle labeled TodayBackground. You
can see this as the gray background of the grid containing the current day. I've
removed this since Outlook indicates the current day differently. I've also added
another row so that the first row contains the day and has a blue background
(this is the LinearGradientBrush in the above XAML) while the second row has
a white background and will show the appointments for that day. More on that
later.
When the current VisualState is set to Today, the following animations take place.
Basically, it changes the background color of the rectangle containing the day
and the border's color and stroke thickness.
<vsm:VisualState x:Name="Today">
<Storyboard>
<ColorAnimation Duration="0" Storyboard.TargetName="StartGradient" Storyboard.TargetProperty="Color" To="#FFF7D275"></ColorAnimation>
<ColorAnimation Duration="0" Storyboard.TargetName="EndGradient" Storyboard.TargetProperty="Color" To="#FFF3B84B"></ColorAnimation>
<ColorAnimation Duration="0" Storyboard.TargetName="BorderBrush" Storyboard.TargetProperty="Color" To="#FFF3B84B"></ColorAnimation>
<DoubleAnimation Duration="0" Storyboard.TargetName="Border" Storyboard.TargetProperty="StrokeThickness" To="2"></DoubleAnimation>
</Storyboard>
</vsm:VisualState>
Listing 9. StoryBoard when VisualState is Today
I've also added a rectangle and named it InactiveBackground. Its opacity is set to
1 when the VisualState is Inactive. You can see this background for days that
are shown on the calendar but is not included in the currently displayed month.
For example, Oct. 31 is shown but is inactive when the current month displayed
is November.
<vsm:VisualState x:Name="Inactive">
<Storyboard>
<ColorAnimation Duration="0" Storyboard.TargetName="selectedText" Storyboard.TargetProperty="Color" To="#FF777777"></ColorAnimation>
<DoubleAnimation Duration="0" Storyboard.TargetName="InactiveBackground" Storyboard.TargetProperty="Opacity" To="1"></DoubleAnimation>
</Storyboard>
</vsm:VisualState>
Listing 10. StoryBoard when VisualState is Inactive
The following figure shows the updated Calendar.

Figure 5. Styled CalendarDayButton
Finalizing the Style
There are some minor things that still need to be done, like setting the margins,
borders, background etc. The most noticeable is the light-blue background at
the top of the Calendar. The background's height resizes proportionally with
the height of the window. This is not the behavior we want. We can remove this
by not specifying the background of the CalendarItem in the Calendar’s control
template. The following figure shows the final Calendar after applying or updating
some margins and adding background to some grid rows.

Figure 6. Final Calendar Style
Adding Appointments
To add appointments, we need to create a custom control that will inherit from the
Calendar control. This will mean that we should move the style definitions from
the window’s resources section into the custom control’s resource dictionary.
This custom control, shown in the code below, will have a variable that will
contain the list of appointments.
/// <summary>
/// Custom calendar control that supports appointments.
/// </summary>
public class MonthViewCalendar : Calendar
{
public static DependencyProperty AppointmentsProperty =
DependencyProperty.Register
(
"Appointments",
typeof(ObservableCollection<Appointment>),
typeof(Calendar)
);
/// <summary>
/// The list of appointments. This is a dependency property.
/// </summary>
public ObservableCollection<Appointment> Appointments
{
get { return (ObservableCollection<Appointment>)GetValue(AppointmentsProperty); } set { SetValue(AppointmentsProperty, value); }
}
static MonthViewCalendar()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MonthViewCalendar), new FrameworkPropertyMetadata(typeof(MonthViewCalendar)));
}
public MonthViewCalendar()
: base()
{
SetValue(AppointmentsProperty, new ObservableCollection<Appointment>());
}
}
Listing 11. Custom Calendar Control
The Appointments collection accepts objects of type Appointment, which is shown below.
/// <summary>
/// The appointment data.
/// </summary>
public class Appointment
{
public string Subject { get; set; }
public DateTime Date { get; set; }
}
Listing 12. Appointment Class
This class contains only a few details. I won’t imitate Outlook’s implementation
of adding appointments. In this implementation, when a user double-clicks on
a CalendarDayButton, the appointment dialog will be shown. The following figure
shows the appointment dialog.

Figure 7. Appointment Dialog
My first idea was to derive from CalendarDayButton. But it impossible as the CalendarDayButton
is a sealed class. After reading Charles Petzold’s article I mentioned in the
Introduction, my only choice is to override the OnMouseDoubleClick method of
the Calendar class. The following shows the overridden method.
protected override void OnMouseDoubleClick(MouseButtonEventArgs e)
{
base.OnMouseDoubleClick(e);
FrameworkElement element = e.OriginalSource as FrameworkElement;
if (element.DataContext is DateTime)
{
AppointmentWindow appointmentWindow = new AppointmentWindow
(
(Appointment appointment) =>
{
Appointments.Add(appointment);
}
);
appointmentWindow.Show();
}
}
Listing 13. The OnMouseDoubleClick Method
The tricky part is how we will know if the user really clicked a CalendarDayButton.
The OriginalSource property of the MouseButtonEventArgs object will not return
an object of type CalendarDayButton. It might return any object in the CalendarDayButton’s
control template, like rectangle or path. Fortunately, the DataContext value
of the CalendarDayButton is inherited by controls deeper in the visual tree.
Thus, if the DataContext property is of type DateTime, we know that the user
clicked on a CalendarDayButton.
The next thing to do is display the appointments. This can be achieved by updating
the CalendarDayButton control template. The basic idea is to add a ListBox where
its ItemsSource property is bound to the Appointments property of the MonthViewCalendar
control. We also need to filter the appointments based on the date of the CalendarDayButton.
I used an IMultiValueConverter for this purpose. The following XAML code is a
part of the updated CalendarDayButton template.
<!-- Appointments -->
<ListBox
x:Name="appointmentsLbx"
Grid.Row="1"
Background="Transparent"
BorderBrush="Transparent"
HorizontalContentAlignment="Stretch"
>
<ListBox.ItemsSource>
<MultiBinding Converter="{StaticResource AppointmentsConverter}">
<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MonthViewCalendar}}" Path="Appointments"/>
<Binding RelativeSource="{RelativeSource Mode=Self}" Path="DataContext"/>
</MultiBinding>
</ListBox.ItemsSource>
<ListBox.ItemTemplate>
<DataTemplate>
<Border Background="#FFDFE8F5" BorderBrush="#FF5D8CC9" BorderThickness="1" CornerRadius="4">
<TextBlock HorizontalAlignment="Center" Text="{Binding Subject}"/>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
<ControlTemplate.Triggers>
<Trigger SourceName="appointmentsLbx" Property="HasItems" Value="False">
<Setter TargetName="appointmentsLbx" Property="Visibility" Value="Hidden"/>
</Trigger>
</ControlTemplate.Triggers>
Listing 14. CalendarDayButton’s Appointments ListBox
I used multi-binding to filter the appointments based on the date on the CalendarDayButton.
This is because we need to pass 2 objects to the IMultiValueConverter: the appointments
collection and the date. The following shows the IMultiValueConverter code.
/// <summary>
/// Gets the appointments for the specified date.
/// </summary>
[ValueConversion(typeof(ObservableCollection<Appointment>), typeof(ObservableCollection<Appointment>))]
public class AppointmentsConverter : IMultiValueConverter
{
#region IMultiValueConverter Members
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
DateTime date = (DateTime)values[1];
ObservableCollection<Appointment> appointments = new ObservableCollection<Appointment>();
foreach (Appointment appointment in (ObservableCollection<Appointment>)values[0])
{
if (appointment.Date.Date == date)
{
appointments.Add(appointment);
}
}
return appointments;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
Listing 15. Appointments Converter
Everything should work now except for 1 minor glitch. The list box’s items do not
get updated immediately after adding an appointment to the collection. This can
be fixed by implementing the INotifyPropertyChanged interface on the MonthViewCalendar
class and raising the PropertyChanged event when an appointment is added. The
following figure shows the calendar with some appointments.

Figure 9. Calendar with Appointments
The Visual Studio 2008 solution can be downloaded here. Note that I haven’t implemented updating an appointment.
Popularity (21700 Views)
| Biography - Michael Detras |
.NET developer. Interested in WPF, Silverlight, and XNA.
My blog
My FAQs |
Article Discussion: Styling the WPF Calendar to Resemble Outlook's Month View Calendar
Tram replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
Hi,
I'm very interested in your topics, i'm designing a Calendar like yours, but in windows application, not in web application.
And I don't know how to do, can you show me the way to do.
Thank you so much.
I'm looking forward your answer.
Best regards.
The calendar is for a WPF application.
Hi Tram,
The Calendar control here is for a WPF application, which is also a kind of a Windows application. If you are developing a Windows Forms application, then I think you could host the WPF control.
Best regards,
Mike
jenn replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
Just wanted to start off by saying what a well put together post this was :)
my question is this:
1. is there a direct link to this download you speak of at code?
and do i need it..
i cant find the download your speaking of.
2. i have started a project in studio.net...using vb.net as the language..am i gonna add this on as a form...and will it have any impact with the current project. if so is there a way to fix it?
i am very new at this, only been at it for a few weeks, so dont really understand the ropes just yet...thank you for your post..it is just what i am trying to accomplish :)
WPF Toolkit
Thanks for reading the article. Ok, I forgot to mention where to download the WPF calender. It is found in the WPF toolkit, which you can download in this link
http://wpf.codeplex.com/releases/view/40535. I haven't check it yet but it may be included already in VS 2020 and .NET 4. If that's the case, you don't need to install it.
I've done this in C# so you need to convert it to VB. I think there are tools out there that you can use to convert C# to VB. You can check Pete O'Hanlon's MoXaml PowerToys
http://peteohanlon.wordpress.com/moxaml-power-toys/ and see if it works for you.
Cheers!
jenn replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
okay...:)
thank you..i went and downloaded everything LOL...I will let ya know how it comes out!
jenn replied
to jenn at Friday, June 10, 2011 5:07 PM
okay i have down loaded the wpf toolkit..how do i install it into visual studio..im sorry, but as i said earlier i am so very new at this
jenn replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
okay..I have downloaded all the converter to go from VB to C..and I have downloaded the toolkit..but as I said earlier, I am very new to this and am not sure how to get the toolkit or the converter into my visual studio. I have them saved to a folder on D drive in hold before placing them on C drive because I am not sure which folder i am suppose to drop this in.
Hi Jenn,
Are you sure you have downloaded the WPF Toolkit windows installer package (MSI)? Just run it and will will automatically install and you can find the controls in Visual Studio. As for the MoXaml Power Toys, you must change the downloaded installer from DOC to ZIP file extension, then run the installer. Just accept the default values. It will also be automatically added to Visual Studio.
Hope this helps,
Mike
jenn replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
hi mike
i am so sorry to say this because i really need exactly what you are talking about here...and the thing of it all is is that i need it in 8 days:(..
I am trying so desperatly to get this to work ..but I guess I am just too new at this to understand. lol..i know very little about visual studio..*sigh*
the way you have it explained is not the problem..it is all well laid out and stuff, it really is just above what I can understand. First of all I started my project off in Visual Basic, only because it was what I started using 8 years ago..before I was so abruptly forced to put the whole adventure away. now, this is wrote in C..LOL...I barely know VB...never mind C! lol..
yes i did get the converter..but i do not understand what you mean by having to change Doc..to..or even how LOL..i right click on the file and go to properties..but then have to pick a program to open it *sigh*
I did download the toolkit..and did extract it..and in my toolbar it shows : Pointer, DataGrid,DatePicker and Calendar. I do not see all of these places you are talking about to change calendar template (cuz between you and me...that calendar in studio as it is is ugly beyond ugly LOL)
it is just so frustrating to finally FIND exactly what I need...to a Tee..and have such a hard time making it all happen :(

Hi Jenn,
The MoXaml Power Toys installer is downloaded in .DOC format so you need to change it to .ZIP. If the .DOC extension is hidden, go to Folder and Search options (found in Explorer) and uncheck the "Hide extensions for known file types" check box. Rename the installer file and change the extension to .ZIP and extract the contents. Having read your situation, this will be a tough one.
Good luck!
Mike
Mario replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
Hi Michael,
First of all, love the work you did with styling the Calendar.
I have one question/issue for you.
Say I have your Calendar and a ComboBox in a StackPanel (ComboBox then your Calendar, vertically), If I click on a day in the Calendar, then mouse over the ComboBox, it is not detecting the mouse over. It's as if the Calendar is capturing focus of input when it has it, and the user must click off of the calendar to restore focus to the outside controls.
This is a problem I've noticed with updating the Calendar dynamically. If it doesn't have focus, it doesn't update.
Let me know if you've seen this, or have suggestions I can attempt.
Thanks,
-Mario

Hi Mario,
Thanks for reading the article. Regarding the problem, I haven't encountered it yet before. I checked it again and you are right. The CalendarItem control is capturing the mouse when you select it. One thing that you could do is to override the PreviewMouseUp event on the MonthViewCalendar control and release the mouse capture. That is just a suggestion that you may try though, as I don't know if there are any possible side effects this could bring. Hope this helps.
Thanks,
Mike
Jebby Fish replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
Hi,
This is a great article and a nice calendar. Thank you so much!
I am new to WPF and am trying to make use of this calendar.
I would like to use it as a user control but encounter issue (the calendar does not show up at all) when i compiled it as DLL and put it in one of the user control (for testing purpose, I just have an empty grid in this user control) i have created.
Would you please shed me some light on which direction should I look into?
Thank you so much in advance! :)
Hi,
Thanks for reading the article. As for your problem, I don't have a clue on why you are encountering this. Could you give me more details like Visual Studio and .NET Framework you are using, any errors in Output Window when you build or rebuild the solution, does it happen in design-time or runtime, etc. Or could you upload a sample solution where you could reproduce the issue? Thanks!
Jebby Fish replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
Hi,
Thanks for the prompt reply. I got this issue taken care of. Thank you! :)
Now I have another question, if I want to attach an event to the listbox (or listItem) for the appointments. How should I do it? I tried to put it in the resource.dictionary; however, I got the following error message:
Error 1 'ResourceDictionary' root element requires a x:Class attribute to support event handlers in the XAML file. Either remove the event handler for the PreviewMouseLeftButtonDown event, or add a x:Class attribute to the root element. Line 455 Position 29.
Would you please shed me some light on this issue. I am sorry if this is a simple, basic question. I am a newbie in WPF. :)
THANKS!!!

Hi,
Do you want to attach an event handler for the PreviewMouseLeftButtonDown event of the ListBox? If so, then you have to attach it programmatically (in code). You can't do it in the ResourceDictionary because this is the place where you put the default style for the Calendar.
So, in the OnApplyTemplate method, you can do this: listBox.PreviewMouseLeftButtonDown += MyHandler;
Jebby Fish replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
wow...
yes... I wanna drag and drop the appointment. You are so smart... :D
May I ask how do I access the listBoxes which are defined in the Generic.xaml?
I have to look again at the code because I forgot most of what I did already. I saw that the ListBox is defined in the CalendarDayButton template, not the Calendar. Unfortunately, this class is sealed (for valid reasons) so we can't get it on the OnApplyTemplate method using GetTemplateChild. You can traverse the visual tree if you want to.
I haven't implemented drag and drop for the calendar that I use in my application, so I can't give you an exact solution. Maybe you could use the CalendarDayButton instead of the ListBox to implement that behavior.
Carl replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
Michael, I'm very new to WPF and XML/XAML and don't know how to construct the XAML files for the 3 new namespaces used in the Generic.XAML calendar template file that is in the WPFToolkit. Can you provide the syntax of the file?
Thanks
Hi Carl,
Sorry for the late response. Have you solve your problem already? Can you give me more details about your problem? That would help a lot. You could also post in the forums. I'm sure you will get a timely answer. Thanks!
Carl replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
Hi Michael,
Thanks for getting back to me, I have solved the original issue. I was not able to get your code to download when selecting the “Here” hyperlink, hyperlink actually worked up on the word “note”. I do have another question though, I have been playing around with your code to try to load appointments by date out of a SQL DB using LINQ when the app launches. I think the below code could be modified to do the task but have no clue how to write it. Any help would be greatly appreciated.
public ObservableCollection<Appointment> Appointments
{
get { return (ObservableCollection<Appointment>)GetValue(AppointmentsProperty); }
set { SetValue(AppointmentsProperty, value); }
}

Changing the control's code to load appointments from an SQL DB is valid. However, that would mean having a code tightly-coupled with a database implementation. I suggest you do it from outside the control, in your application. Load the dates from the database, create the calendar, then fill up the Appointments property. If you need to show other data, then you can add more properties to the Appointment class.
akshay replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
Hey
I m new at Visual studio 2010.. and i want to make the calendar like the one you have made in this article... first of all let me say its a fantastic article... but all these commands are invalid in wpf 2010... so is it possible if you can help post the commands with visual studio 2010... the Monthcalendar is already included in visual studio 2010.... but for some reason i cant figure out a way to make changes to dimensions... it still shows only one calendar... that too in a very smalll rectangle..... any help will be gretly appreaciated.
Thanks
Akshay Chaudhary
Gilles replied
to akshay at Friday, June 10, 2011 5:07 PM
Hi there,
Great article you wrote there. It's what I was looking for. However, in my WPF app, I need to display events (Appointments in your terminology) which span multiple days. I don't really see how I could modify your control to take this into account. Maybe you've got an idea?
Let's say the event spans december 13th, 14th and 15th. I could add 3 different single day events. However, I want to visually distinguish between the start day, the end day and the days inbetween. How can I do that?
Article Discussion: Styling the WPF Calendar to Resemble Outlook's Month View Calendar
Robert replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
Hej Michael, Great job with this calendar.
Michael. I got so far, that I made a new method (GetMyAppointments()) in to the MonthViewCalendar class, which I call from MainWindow. I made the new appointments and I added to the Appointments list, but I do not know how to call the AppointmentConvert method with the new information, and in this case, I can't show my appointments in the calendar.
I tried to watch trough step by step, how you did it from the AppointmentWindow, where your code is jumping from the PropertyChanged method to the AppointmentConverter. I tried to use the same line in my method, but I get an error.
Thank you in anticipation for your help.
Sincerely
Robert
Hi Robert,
Thanks for reading the article. If I understand it correctly, the UI was not informed that the Appointments list has been changed. Usually, it will only take raising the PropertyChanged event to solve this. What kind of error are you getting? A short code snippet will also help. Thanks!
Michael
Robert replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
Hi Michael,
Thank you for your fast answer.
The error I catch is: "Object reference not set to an instance of an object"
I get this error when I copy the PropertyChanged code line from your override OnMouseButtonClick method.
I will send you the whole method I wrote later on today, if it's needed.
Thanks,
Robert
Yes please upload or post your code snippet somewhere and give me a link so that I can check. Thanks!
Robert replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
Hi Michael,
Here are
the code you needed. (Check out the .docx file)
Thank you
for your help.
Open here
Robert replied
to Robert at Friday, June 10, 2011 5:07 PM
Hi Michael,
Did you find the snippet? Could you confirm it?
regards
Robert
Robert replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
Hi Michael,
Did you find the snippet? Could you confirm it?
regards
Robert
Hi Robert,
Yes, I found the code snippet. I would like to create a similar scenario on my own machine so that I can give a definite answer, but currently don't have the time to do so. I'll try it out later. It might be related to timing since the PropertyChanged event is still null after the Loaded event of the Window is raised. I'll get back to you later. Thanks!
Regards,
Michael
Hi Robert,
I see that you've added a MonthViewCalendar instance variable to your MainWindow class. And you've called your method in the Loaded event handler. The problem is that the MonthViewCalendar you just defined is not really a child/descendant of the main window, thus the bindings aren't set even after the window is loaded. I assume you put another MonthViewCalendar in the MainWindow XAML, right? Give it a name and use that to call your method, and remove the other MonthViewCalendar variable. Hope this helps.
Best regards,
Michael
Robert replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
Hi Michael,
Thank you so much using time on me and my pitty scool project. I do not know how to do that. I used your program part as template and I did not change anything in it, except the small method I wrote. I can only program C# and I do not know anything about xaml or xml. I do not understand what you mean. Is it possible for you to explain it on "dummy" language?
I really would like to make it work in my project.
Sorry for using your time!
Robert
Hi Robert,
I see, there is nothing to be sorry of. If you open the MainWindow.xaml file, you could see the following line:
<local:MonthViewCalendar/>
You could give it a name like this:
<local:MonthViewCalendar x:Name="calendar"/>
And the MainWindow.xaml.cs would look like this:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainWindow_Loaded);
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
calendar.LoadAppointments();
}
}
Michael
Robert replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
I found the problem.
There should be:
Loaded += new RoutedEventHandler(Window_Loaded);
and not
Loaded += new RoutedEventHandler(MainWindow_Loaded);
Its working Michael. So we can conclude, that this is one of the way to load appointment in to the Month Calender View from a saved database or datafile.
Thank you for your help!
Friendly regards
Robert
Robert replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
Hey Michael,
I have a final question.
For some kind of mysterious reason, I am getting my appointments two times for the same day. I checked the lists, they made correctly.
Any suggestion?
kind regards
Robert
Maarten replied
to Robert at Friday, June 10, 2011 5:07 PM
Hi,
This is my first application ever in WPF and I'm doing this for schoolwork.
My question was this: I'm allways getting this error "Property 'CalendarItemStyle' was not found in type 'control'"
Hope to hear you soon.
Kind regards
Robert replied
to Maarten at Friday, June 10, 2011 5:07 PM
Hej Maarten,
Did you get the openSource CustomCalendar from here? Did you download and installed the WPFToolkit?
Regards Robert
Maarten replied
to Robert at Friday, June 10, 2011 5:07 PM
Where can I find those? I've downloaded the WPF Toolkit but i can't install it.
Thanks in advance!
Maarten replied
to Maarten at Friday, June 10, 2011 5:07 PM
Ok sorry for that, the WPF Toolkit was allready installed. I can't find the CustomCalender though.
Robert replied
to Maarten at Friday, June 10, 2011 5:07 PM
Hej,
Try to look just under Figure 9.
there is a link.
regards
Robert
Sreenath KV replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
I want to add MouseLeftButtonDown event of the ListBox but was not able to do it. I tried the method you mentioned for Jebby Fish. I want to popup another form when i click a list box item. how can i do it? i am new to WPF. can you explain it in a 'dummy language' .....
Sreenath KV replied
to Michael Detras at Friday, June 10, 2011 5:07 PM
Also , i would like to know how to delete an appointment that have been added to the list.