Telerik blogs

A common scenario when using the ScheduleView control is to have custom appointments with additional properties that are not by default included in the standard Appointment class. In these cases simply extending the Appointment class is not enough, because we have some more requirements – we want our custom properties to support cancelation of editing (like the standard one does), we want to allow the user to edit the custom properties using the Appointment edit dialog and eventually to render values of the custom properties in the AppointmentItem or/and its ToolTip.

In this article we will go through the following steps:

  • Create a custom appointment class and populate the ScheduleView with custom appointments
  • Change the look of the default Appointment dialog to be able to edit the new data of the custom appointment
  • Change the look and feel of the AppointmentItem and its ToolTip to display the new data

Creating a custom appointment class

To create a custom appointment class you need to either implement the IAppointment interface or to inherit from one of the classes that already implement this interface – AppointmentBase (the base implementation of the interface) or Appointment (a more extended implementation). It is very important to provide your own implementations for the Copy and CopyFrom methods as they are used intensively by the editing process of the ScheduleView control. Implementing the interface will force you to implement them, but if you inherit from one of the base classes you should keep this in mind.

We will create a simple task tracking system. The system will need an additional field for the task progress – indication of whether it is finished, not finished or in progress. In order to enable editing in transactions of the new property we need to use the Storage method of the AppointmentBase class to access the instance which owns the fields.

Here is the code of the Task class (our custom appointment):

public class Task : Appointment
{
 private bool isDone;
 
 public bool IsDone
    {
        get
        {
 return this.Storage<Task>().isDone;
        }
 
        set
        {
            var storage = this.Storage<Task>();
 if (storage.isDone != value)
            {
                storage.isDone = value;
 this.OnPropertyChanged(() => this.IsDone);
            }
        }
    }
 
 public override IAppointment Copy()
    {
        var newAppointment = new Task();
        newAppointment.CopyFrom(this);
 return newAppointment;
    }
 
 public override void CopyFrom(IAppointment other)
    {
        var task = other as Task;
 if (task != null)
        {
 this.IsDone = task.IsDone;
        }
 
 base.CopyFrom(other);
    }
}

 

It is very important to set the AppointmentsSource to be IList<Task>, because this is the way to tell the ScheduleView that the new appointments should be of type Task. In our case we will create an ObservableCollection<Task> using the following approach:

var today = DateTime.Today;
 
var data = new ObservableCollection<Task>(Enumerable.Range(9, 14).Select(i =>
 new Task
    {
        Start = today.AddMinutes(i * 60 + 15),
        End = today.AddMinutes((i + 1) * 60),
        Subject = string.Format("Task num. {0}", i),
        IsDone = today.AddMinutes((i + 1) * 60) < DateTime.Now
    }));
 
this.DataContext = data;

 

Creating a custom Appointment Dialog

To create a custom appointment dialog you need to change the EditAppointmentDialogStyle property of the ScheduleView control. The DataContext of this style target is a AppointmentDialogViewModel object. This class contains all needed data for editing an appointment including the Appointment itself. It can be reached by using the Occurrence property of the ViewModel and its Appointment property.

Now we would like to add a checkbox for our new property and to bind it. Here is the code for this:

<CheckBox Content="Is done?" IsChecked="{Binding Occurrence.Appointment.IsDone, Mode=TwoWay}"/>

 As we can see from this example we can bind to our custom properties trough Occurrence.Appointment.

Changing the Style of the AppointmentItem

Next, we need to change the ContentTemplate of the AppointmentItem control to indicate which Tasks are done and which are not. To do that, we need to change the AppointmentStyleSelector property of the RadScheduleView. The DataContext in the AppointmentItem ContentTemplate represents an AppointmentItemProxy, which holds the most important properties of the Appointment and the Appointment itself.

What we are going to do is to display a green dot for all tasks that are done. We will achieve this by adding a green dot in the ContentTemplate and then binding its Visibility to the IsDone property of the Task through a converter. Here is the code for this:

<Ellipse Fill="Green" Width="15" Height="15" VerticalAlignment="Center" 
Margin
="2" HorizontalAlignment="Center"
Visibility
="{Binding Appointment.IsDone,
Converter={StaticResource BooleanToVisibilityConverter}}"
/>

 

Changing the template of the Appointment Tooltip

To change the appearance of the Appointment Tooltip you need to use the TooltipTemplate property of the ScheduleView. The DataContext in this template is once again of type AppointmentItemProxy so we could use the same approach we used in the AppointmentItem ContentTemplate.

Now we will add the text (Done) only for the tasks which are already done. Here is the code for this:

<TextBlock Text="(Done)" Grid.Row="1" HorizontalAlignment="Right" 
Visibility
="{Binding Appointment.IsDone, C
onverter={StaticResource BooleanToVisibilityConverter}}"

FontStyle
="Italic" />

 

By completing this last modification, we have reached the end of the process needed to create a custom appointment in RadScheduleView control.

You can download the complete source code of the demo application from here.


Comments

Comments are disabled in preview mode.