Appointment views can be customized on global level, per calendar view (i.e. Day, Week, Month or Timeline) and/or on a per appointment basis.

  • Use property Appointment.ViewDefinitions to define customizations on a per appointment basis.
  • Use property CalendarModel.AppointmentViewDefinitions or CalendarView.ViewCustomizations to define customizations on a global level.

CalendarView.ViewCustomizations is a property of type CalendarViewCustomizations, which in turn has three properties for customizing different aspects of the calendar’s view: GlobalAppointmentViewDefinitions, DayTimeSlotAppearances, and MonthDayAppearances. To customize appointment views, use the GlobalAppointmentViewDefinitions property.

Note: The dimensions of appointment views (width and height) are set internally. The height of appointments in Month view, Timeline view and multi-day appointments in the Week and Day views are constant. The values used are defined in ScheduleSettings (DevComponents.Silverlight.Schedule) and can be changed at run time. The properties and default values are: MonthViewAppointmentHeight = 18, TimelineViewAppointmentHeight = 21, WeekViewMultiDayAppointmentHeight = 18.

The type which defines a set of appointment view customizations is AppointmentViewDefinitionSet. While AppointmentViewDefinitionSet is a collection of AppointmentViewDefinition instances, it also exposes the following dependency properties which can be used to set view properties for appointments in all calendar views:

  • CommonBackground – A Brush to use for the background of the appointments in all view types (Day, Week, Month and Timeline)
  • CommonBorderBrush – A Brush to use for Border of the appointments in all view types.
  • CommonCornerRadius – A CornerRadius for appointments in all view types.
  • CommonToolTip – A tooltip for appointments in all view types. This value can be an instance of DevComponents.Silverlight.Controls.SuperToolTip or System.Windows.Controls.ToolTip. Alternatively, it can be any Clr object in which case the value is set as Content of a SuperToolTip.
  • CommonImageSource – An image for appointments in all view types. Value may be a string or Uri specifying the image location or it may be an ImageSource object.
  • CommonSelectionBorderBrush – A Brush for the borders of appointments in all view types when the appointment is selected.

Setting properties on a per calendar view basis is supported via class AppiontmentViewDefinition. Values set in AppointmentViewDefinition ALWAYS take precedence over the corresponding values defined in the definition set. The definition set exposes four properties of type AppointmentViewDefinition, one for each calendar view type: Day, Week, Month and Timeline. An appointment view definition exposes the following dependency properties:

  • AppointmentTemplate – defines a DataTemplate to be used as ContentTemplate for an AppointmentView control. AppointmentView control is a ContentControl. By default, the Content property is set equal to the DataContext property, which is an instance of DevComponents.Silverlight.Calendar.ViewModel.AppointmentViewModel.
  • Background – defines the brush to use for background of the appointment view. This value is ignored if a valid value for Appointment.CategoryColor is set.
  • BorderBrush – defines the brush to use for the border of the appointment view. This value is ignored if a value for Appointment.CategoryColor is set to one of the built-in values.
  • CornerRadius – defines the corner radius for the appointment view. Default is 0.
  • CustomData – a place to put custom data object, which can then be bound against in AppointmentTemplate and/or ToolTipTemplate.
  • ImageSource – specifies an image to be associated with the appointment. Value may be a string or Uri specifying the image location or it may be an ImageSource object.
  • MultiDayAppointmentTemplate – defines a DataTemplate to be used for views of multi-day appointments. Note: for Month and Timeline views, if this value is unset while a value for AppointmentTemplate is provided, then the value of AppointmemtTemplate is used for all appointments, both single day and multi-day.
  • SelectionBorderBrush – a Brush to use for the appointment border when selected. The default value is provided by resource with key of “AppointmentSelectedBorderBrush”;
  • ToolTip – the tool tip that is associated with the appointment in the applicable view. This value can be an instance of DevComponents.Silverlight.Controls.SuperToolTip or System.Windows.Controls.ToolTip. Alternatively, it can be any Clr object in which case the value is set as Content of a SuperToolTip.
  • ToolTipTemplate – the ContentTemplate to use for the SuperToolTip which is created for the appointment view. By default, a SuperToolTip is created and its content property set to the instance of AppointmentViewModel associated with the appointment. If this value is unset, the default tool tip content template is defined by the resource with key defined by the static property AppointmentView.DefaultToolTipContentTemplateKey,  which has a default value of “StandardAppointmentToolTipTemplate”.

Note that it is possible to derive from either or both AppointmentViewDefinitionSet and AppointmentViewDefinition for even greater customization possibilities. In support of this scenario, property AppointmentViewDefinition.CurrentView will always contain the active instance of AppointmentViewModel which is providing data for the current view, and which can be used for run-time property modifications.

Property inheritance is fully supported. Highest precedence are values provided by appointment view definition taken from a definition set applied directly to an appointment. Next highest precedence are values  set on appointment definitions taken from a  global definition set applied to either the calendar model directly or indirectly via the calendar control itself. If neither of these have a value set, then the common values provided by the definition set are checked, with values set on a set applied directly to an appointment taking precedence over values of a global set.

Here is an example of setting an image to be used for Week view and Day views in an individual appointment:

string url = "images/don.png";
if (appointment.ViewDefinitions == null)
    appointment.ViewDefinitions = new AppointmentViewDefinitionSet();
appointment.ViewDefinitions.Day.ImageSourceUri = appointment.ViewDefinitions.Week.ImageSourceUri = new Uri(url, UriKind.Relative);

Global appointment view definition set can be defined and applied in Xaml. Here is an example of a global definition set being set up and applied in Xaml, taken from the sample ScheduleControlMVVMSample:

<schedule:CalendarViewCustomizations x:Key="ViewCustomizations">
    <schedule:CalendarViewCustomizations.GlobalAppointmentViewDefinitions>
        <schedule:AppointmentViewDefinitionSet>
            <schedule:AppointmentViewDefinitionSet.CommonToolTip>
                <controls:SuperToolTip Style="{StaticResource AppointmentToolTipStyle}" />
            </schedule:AppointmentViewDefinitionSet.CommonToolTip>
            <schedule:AppointmentViewDefinitionSet.Day>
                <schedule:AppointmentViewDefinition AppointmentTemplate="{StaticResource CustomDayViewAppointmentTemplate}" />
            </schedule:AppointmentViewDefinitionSet.Day>
        </schedule:AppointmentViewDefinitionSet>
    </schedule:CalendarViewCustomizations.GlobalAppointmentViewDefinitions>
</schedule:CalendarViewCustomizations>

This customization is applied to the CalendarView by setting ViewCustomizations property as such:

ViewCustomizations="{StaticResource CalendarViewCustomizations}"

AppointmentViewModel

Appointment view content templates and tool tip content templates are both bound by default to an instance of AppointmentViewModel. AppointmentViewModel is a wrapper for an Appointment. Here are the properties exposed by AppointmentViewModel which are available in a binding context. Note that the return values for all these properties take into account whether there is an effective AppointmentViewDefinition and if so, resolve the effective value based on property inheritance.

  • Appointment – The actual Appointment instance which the view model is a wrapper for.
  • ViewDefinition – The effective appointment view definition. This instance will have all properties bound to the most relevant source, based on the inheritance chain.
  • ImageSource – Gets or Sets the value that is bound to by an Image’s ImagesSource proeprty. By default, it will return the value for ImageSource on the effective appointment view definition, or null.
  • OwnerKey – gets or set the Key of the appointment’s owner. Setting this value effectively will change the appointment’s owner.
  • Owner – gets the instance of class Owner which represents the appointment’s owner.
  • IsLocked – get or set the appointment’s Locked property.
  • IsSelected – get or set the appointment’s IsSelected property.
  • IsRecurrenceRoot – gets whether the appointment is the root appointment of a recurrance.
  • IsRecurring – gets whether the appointment is part of a recurring appointment.
  • StartTime – gets or sets the appointment start time.
  • EndTime – gets or sets the appointment end time.
  • Subject – gets or sets the appointment’s subject.
  • Description – gets or sets the appointment’s description.
  • CategoryColor – gets or sets the value for appointment CategoryColor.
  • TimeMarkedAs – gets or sets the value for appointment TimeMarkedAs.
  • CornerRadius – gets the corner radius for appointment view.
  • SelectionBorderBrush – gets the brush to use for border when appointment is selected.
  • Background – gets effective background brush for appointment.
  • BorderBrush – gets effective border brush for the appointment.
  • TimeMarkerBrush – gets effective brush used for the time marker.
  • CurrentViewType – gets the CalendarViewType of the currently active view (i.e. Month, Week, Day or Timeline).

Default Templates

Default AppointmentView and ToolTip ContentTemplates are merged at run time into the current Application’s resources dictionary. For your convenience, these templates are provided here. You can use them as starting points for your own customized templates.

Note that all of the default templates can be overridden by defining a new value with the same key in your Application.Resources section. This is another way to customize appointments on a global level.

Appointment View Templates

<!-- Defines the default DataTemplate used for an appointment in the Month view. -->
<DataTemplate x:Key="MonthViewAppointmentTemplate">
    <TextBlock Margin="5,0,1,0">
        <Run Text="{Binding Subject}" />
        <Run Text="{Binding StartTime, StringFormat=' {0:t}'}" />
    </TextBlock>
</DataTemplate>
 
<!-- Defines the default DataTemplate for a multi-day appointment in the month view. -->
<DataTemplate x:Key="MonthViewMultiDayAppointmentTemplate">
    <TextBlock Margin="5,0,1,0">
        <Run Text="{Binding Subject}" />
        <Run Text="{Binding StartTime, StringFormat=' {0:MMMM dd}'}" />
        <Run Text="{Binding EndTime, StringFormat='thru {0:MMMM dd}'}" />
        <Run Text="{Binding StartTime, StringFormat='- {0:t}'}" />
        <Run Text="{Binding EndTime, StringFormat='to {0:t}'}" />
    </TextBlock>
</DataTemplate>
 
<!-- Default DataTemplate for an appointment in the Week or Day views. -->
<DataTemplate x:Key="WeekViewAppointmentTemplate">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Border Grid.RowSpan="2" Width="5" HorizontalAlignment="Left" BorderThickness="0,0,1,0" CornerRadius="{Binding CornerRadius}"
                BorderBrush="{Binding BorderBrush}" Background="{Binding TimeMarkerBrush}"
                Visibility="{Binding TimeMarkerVisibility}" />
        <Image Margin="3,3,0,0" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" MaxHeight="20" MaxWidth="20" Stretch="Uniform"
                Source="{Binding ViewDefinition.ImageSource}" 
                Visibility="{Binding ViewDefinition.ImageSource, Converter={StaticResource nullableToVisibilityConverter}}"/>
        <TextBlock Grid.Column="2" Margin="3,3,0,0" TextWrapping="Wrap" Text="{Binding Subject}" />
        <TextBlock Margin="3,3,0,0" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" TextWrapping="Wrap" Text="{Binding Description}" />
    </Grid>
</DataTemplate>
 
<!-- Defines the default data template for a multi-day appointment in the Week or Day views. -->
<DataTemplate x:Key="WeekViewMultiDayAppointmentTemplate">
    <TextBlock Margin="10,0,5,0" HorizontalAlignment="Left">
        <Run Text="{Binding Subject}" />
        <Run Text="{Binding StartTime, StringFormat=' {0:MMMM dd}'}" />
        <Run Text="{Binding EndTime, StringFormat='thru {0:MMMM dd}'}" />
        <Run Text="{Binding StartTime, StringFormat='- {0:t}'}" />
        <Run Text="{Binding EndTime, StringFormat='to {0:t}'}" />
    </TextBlock>
</DataTemplate>
 
<!-- Defines the default data template for an appointment in the Timeline view. -->
<DataTemplate x:Key="TimelineViewAppointmentTemplate">
    <TextBlock Margin="10,0,5,0" HorizontalAlignment="Left">
        <Run Text="{Binding Subject}" />
        <Run Text="{Binding StartTime, StringFormat=' {0:MMMM dd}'}" />
        <Run Text="{Binding EndTime, StringFormat='thru {0:MMMM dd}'}" />
        <Run Text="{Binding StartTime, StringFormat='- {0:t}'}" />
        <Run Text="{Binding EndTime, StringFormat='to {0:t}'}" />
    </TextBlock>
</DataTemplate>

Tool Tip Templates

<!-- Defines the default DataTemplate for appointment tool tips in Day, Week and Timeline views. -->
<DataTemplate x:Key="StandardAppointmentToolTipTemplate">
    <Grid MaxWidth="300">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <TextBlock Text="{Binding Subject}" FontWeight="Bold"/>
        <TextBlock Grid.Row="1">
            <Run Text="{Binding StartTime, StringFormat='t'}" />
            <Run Text="{Binding EndTime, StringFormat='to {0:t}'}" />
        </TextBlock>
        <TextBlock Grid.Row="2" Text="{Binding Description}" TextWrapping="Wrap" />
    </Grid>        
</DataTemplate>
 
<!-- Defines the default DataTemplate for the Month Appointment View's ToolTip -->
<DataTemplate x:Key="MonthCalloutToolTipTemplate">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition />
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Border Height="10" Width="10" HorizontalAlignment="Center" VerticalAlignment="Center" CornerRadius="3" 
                BorderThickness="1" Background="{Binding Background}" BorderBrush="{Binding BorderBrush}" />
        <TextBlock Grid.Column="1" Margin="7,0,8,0" HorizontalAlignment="Left" Text="{Binding Subject}"
                    FontWeight="Bold" TextWrapping="Wrap" ctrls:DynamicResource.ForegroundKey="CalloutSubjectForeground" />
        <TextBlock Margin="0,0,5,0" Grid.Column="2" HorizontalAlignment="Right" ctrls:DynamicResource.ForegroundKey="CalloutTimeForeground">
            <Run Text="{Binding StartTime, StringFormat='t'}" />
            <Run Text="{Binding EndTime, StringFormat='to {0:t}'}" />
        </TextBlock>
        <Line Grid.ColumnSpan="3" Grid.Row="1" Margin="0,3" StrokeThickness="1" X1="0" X2="1" Y1="0" Y2="0" Stretch="Fill" 
                ctrls:DynamicResource.StrokeKey="CalloutSeparatorBorder"
                Visibility="{Binding Description, Converter={StaticResource nullableToVisibilityConverter}}" />
        <Grid Grid.Row="2" Grid.ColumnSpan="3">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Image Margin="0,0,5,0" VerticalAlignment="Top" MaxHeight="20" MaxWidth="20" Stretch="Uniform" Source="{Binding ImageSource}"
                    Visibility="{Binding ImageSource, Converter={StaticResource nullableToVisibilityConverter}}"/>
            <TextBlock MaxWidth="370" Grid.Column="1" VerticalAlignment="Center" Text="{Binding Description}" TextWrapping="Wrap" HorizontalAlignment="Left" 
                            ctrls:DynamicResource.ForegroundKey="CalloutDescriptionForeground" />
        </Grid>
    </Grid>
</DataTemplate>

AppointmentView based controls default Style and Template

If absolutely necessary, appointment views can be modified via the appointment view control’s Style property using implicit Style inheritance provided by Silverlight. Note that using implicit styling of appointment views it is only possible to customize appointments on the global level. Views for individual appointments cannot be given custom Styles or Templates.

Appointment view controls are controls which derive from AppointmentViewAppointmentView itself is an abstract class. There are specific Appointment View controls defined for each of the calendar view types. The concrete AppointmentView controls are:

  • MonthAppointmemtView provides view of single day appointment in the Month view.
  • MonthMultiDaySegmentAppointmentView – provides view of a segment of a multi-day appointment in the Month view. A segment represents the time span of the appointment which is contained by a single Week.
  • WeekAppointmentView – provides view of a single day appointment in the Week and Day views.
  • WeekMultiDayAppointmentView – provides view of a multi-day appointment in the Week and Day views.
  • TimelineAppointmentView – provides view of an appointment in the Timeline view.

Default control templates are provided for convenience. You can use them as starting point for your customization.

Month Appointment View Control Templates

Default control templatae for MonthAppointmentView:

<ControlTemplate TargetType="sch:MonthAppointmentView">
    <Grid>
        <Border Background="{Binding Background}" BorderBrush="{Binding BorderBrush}" BorderThickness="1" CornerRadius="{Binding CornerRadius}" />
        <ContentPresenter VerticalAlignment="Center" Content="{TemplateBinding DataContext}" ContentTemplate="{TemplateBinding AppointmentTemplate}" />
        <Border Name="SelectedBorder" BorderThickness="2" BorderBrush="{Binding SelectionBorderBrush}" Opacity="0" CornerRadius="{Binding CornerRadius}" />
        <sch:MonthAppointmentMoveThumb x:Name="MoveThumb" />
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="SelectedStates">
                <VisualState x:Name="Unselected" />
                <VisualState x:Name="Selected">
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.01" />
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
            <VisualStateGroup x:Name="RecurrenceStates">
                <VisualState x:Name="NonRecurring" />
                <VisualState x:Name="RecurrenceRoot" />
                <VisualState x:Name="RecurringInstance">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MoveThumb" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</ControlTemplate>

Default control template for MonthMultiDaySegmentAppointmentView:

<ControlTemplate TargetType="sch:MonthMultiDaySegmentAppointmentView">
    <Grid>                        
        <Border Name="NormalBorder" Background="{Binding Background}" BorderBrush="{Binding BorderBrush}" BorderThickness="1" CornerRadius="{Binding CornerRadius}" />
        <ContentPresenter Content="{TemplateBinding DataContext}" ContentTemplate="{TemplateBinding AppointmentTemplate}" VerticalAlignment="Center" />
        <Border Name="SelectedBorder" BorderThickness="2" BorderBrush="{Binding SelectionBorderBrush}" Opacity="0" CornerRadius="{Binding CornerRadius}" />
        <sch:MonthAppointmentMoveThumb x:Name="MoveThumb" />
        <Grid Name="MoveResizeGroup" Visibility="Collapsed">
            <sch:MonthAppointmentResizeThumb x:Name="ResizeLeft" Margin="-2,0,0,0" HorizontalAlignment="Left" Visibility="Collapsed" />
            <sch:MonthAppointmentResizeThumb x:Name="ResizeRight" Margin="0,0,-2,0" HorizontalAlignment="Right" Visibility="Collapsed" />
        </Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="SelectedStates">
                <VisualState x:Name="Unselected" />
                <VisualState x:Name="Selected">
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0" />
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MoveResizeGroup" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
            <VisualStateGroup x:Name="RecurrenceStates">
                <VisualState x:Name="NonRecurring" />
                <VisualState x:Name="RecurrenceRoot" />
                <VisualState x:Name="RecurringInstance">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ResizeLeft" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ResizeRight" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MoveThumb" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
            <VisualStateGroup x:Name="BoundaryStates">
                <VisualState x:Name="Closed">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ResizeLeft" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ResizeRight" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="OpenRight">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalBorder" Storyboard.TargetProperty="BorderThickness">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="1,1,0,1" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="BorderThickness">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="2,2,0,2" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ResizeLeft" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="OpenLeft">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalBorder" Storyboard.TargetProperty="BorderThickness">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0,1,1,1" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="BorderThickness">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0,2,2,2" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ResizeRight" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="OpenBothEnds">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalBorder" Storyboard.TargetProperty="BorderThickness">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0,1" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="BorderThickness">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0,2" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</ControlTemplate>

Day/Week Appointment View Control Templates

Default control template for WeekAppointmentView:

<ControlTemplate TargetType="sch:WeekAppointmentView">
    <Grid>                
        <Grid.Resources>
            <ctrls:BoolToVisibilityConverter x:Key="boolToVisibilityConverter" />
        </Grid.Resources>
        <Border Background="{Binding Background}" BorderBrush="{Binding BorderBrush}" BorderThickness="1" CornerRadius="{Binding CornerRadius}" />
        <ContentPresenter Content="{TemplateBinding DataContext}" ContentTemplate="{TemplateBinding AppointmentTemplate}" />
        <Border Name="SelectedBorder" Background="Transparent" BorderThickness="2" Opacity="0" BorderBrush="{Binding SelectionBorderBrush}" CornerRadius="{Binding CornerRadius}" />
        <sch:WeekAppointmentMoveThumb x:Name="MoveThumb" Margin="0,4" Cursor="Hand"
                                        Visibility="{Binding Path=IsLocked, Converter={StaticResource boolToVisibilityConverter}, ConverterParameter=Inverse}" />
        <Grid Name="MoveResizeGroup" Visibility="{Binding Path=IsLocked, Converter={StaticResource boolToVisibilityConverter}, ConverterParameter=Inverse}" >
            <sch:WeekAppointmentMoveThumb x:Name="ResizeTop" Opacity="0" VerticalAlignment="Top" Margin="0,-2,0,0" Cursor="SizeNS" Style="{StaticResource ResizeThumbStyle}" />
            <sch:WeekAppointmentMoveThumb x:Name="ResizeBottom" Opacity="0" VerticalAlignment="Bottom" Margin="0,0,0,-2" Cursor="SizeNS" Style="{StaticResource ResizeThumbStyle}" />
        </Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="SelectedStates">
                <VisualState x:Name="Unselected" />
                <VisualState x:Name="Selected">
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="ResizeTop" Storyboard.TargetProperty="Opacity" Duration="0" To="1" />
                        <DoubleAnimation Storyboard.TargetName="ResizeBottom" Storyboard.TargetProperty="Opacity" Duration="0" To="1" />
                        <DoubleAnimation Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="Opacity" Duration="0" To="1" />
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>                            
            <VisualStateGroup x:Name="RecurrenceStates">
                <VisualState x:Name="NonRecurring" />
                <VisualState x:Name="RecurrenceRoot" />
                <VisualState x:Name="RecurringInstance">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ResizeTop" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ResizeBottom" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MoveThumb" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</ControlTemplate>

Default control template for WeekMultiDayAppointmentView:

<ControlTemplate TargetType="sch:WeekMultiDayAppointmentView">
    <Grid>
        <Border Name="NormalBorder" Background="{Binding Background}" BorderBrush="{Binding BorderBrush}" BorderThickness="1" CornerRadius="{Binding CornerRadius}" />
        <ContentPresenter Content="{TemplateBinding DataContext}" ContentTemplate="{TemplateBinding AppointmentTemplate}" />
        <Border Name="SelectedBorder" BorderThickness="2" BorderBrush="{Binding SelectionBorderBrush}" Opacity="0" CornerRadius="{Binding CornerRadius}" />
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="SelectedStates">
                <VisualState x:Name="Unselected" />
                <VisualState x:Name="Selected">
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.01" />
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
            <VisualStateGroup x:Name="BoundaryStates">
                <VisualState x:Name="Closed" />
                <VisualState x:Name="OpenRight">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalBorder" Storyboard.TargetProperty="BorderThickness">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="1,1,0,1" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="BorderThickness">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="2,2,0,2" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="OpenLeft">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalBorder" Storyboard.TargetProperty="BorderThickness">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0,1,1,1" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="BorderThickness">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0,2,2,2" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="OpenBothEnds">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalBorder" Storyboard.TargetProperty="BorderThickness">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0,1" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="BorderThickness">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0,2" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</ControlTemplate>

Timeline Appointment View Control Templates

Default control template for TimelineAppointmentView:

<ControlTemplate TargetType="sch:TimelineAppointmentView">
    <Grid>
        <Border Name="NormalBorder" Background="{Binding Background}" BorderBrush="{Binding BorderBrush}" BorderThickness="1" CornerRadius="{Binding CornerRadius}" />
        <ContentPresenter Content="{TemplateBinding DataContext}" ContentTemplate="{TemplateBinding AppointmentTemplate}" VerticalAlignment="Center" />
        <Border Name="SelectedBorder" Background="{Binding BackgroundBrush}" BorderThickness="2" BorderBrush="{Binding SelectionBorderBrush}" Opacity="0" CornerRadius="{Binding CornerRadius}" />
        <sch:TimelineAppointmentMoveThumb x:Name="MoveThumb" Margin="4,0" Cursor="Hand"/>
        <Grid Name="MoveResizeGroup" Visibility="Collapsed">
            <sch:TimelineAppointmentMoveThumb x:Name="ResizeLeft" HorizontalAlignment="Left" Margin="-2,0,0,0" Cursor="SizeWE" Style="{StaticResource ResizeThumbStyle}" />
            <sch:TimelineAppointmentMoveThumb x:Name="ResizeRight" HorizontalAlignment="Right" Margin="0,0,-2,0" Cursor="SizeWE" Style="{StaticResource ResizeThumbStyle}" />
        </Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="SelectedStates">
                <VisualState x:Name="Unselected" />
                <VisualState x:Name="Selected">
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0" />
                        <DoubleAnimation Storyboard.TargetName="NormalBorder" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0" />
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MoveResizeGroup" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
            <VisualStateGroup x:Name="RecurrenceStates">
                <VisualState x:Name="NonRecurring" />
                <VisualState x:Name="RecurrenceRoot" />
                <VisualState x:Name="RecurringInstance">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ResizeLeft" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ResizeRight" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MoveThumb" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
            <VisualStateGroup x:Name="BoundaryStates">
                <VisualState x:Name="Closed" />                                    
                <VisualState x:Name="OpenRight">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalBorder" Storyboard.TargetProperty="BorderThickness">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="1,1,0,1" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="BorderThickness">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="2,2,0,2" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ResizeRight" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="OpenLeft">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalBorder" Storyboard.TargetProperty="BorderThickness">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0,1,1,1" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="BorderThickness">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0,2,2,2" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ResizeLeft" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="OpenBothEnds">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalBorder" Storyboard.TargetProperty="BorderThickness">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0,1" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="BorderThickness">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0,2" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ResizeRight" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ResizeLeft" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</ControlTemplate>

Related posts:

  1. Silverlight Toolbar Quick Start Guide
  2. SuperToolTip Control
  3. Circular Progress Control (Silverlight) Quick Start Guide
  4. Customizing Month View Days in Silverlight Schedule
  5. Rating Control for Silverlight Quick Start Guide