Skip to main content Skip to footer

Customizing Scheduler for Custom Data

The C1Scheduler control provides an appointment data model common to most scheduling applications. This model includes data storage for the default appointment fields:

Appointment Model

Subject

Required

Text

Location

Required

Text

Start

Required

Date/Time

End

Required

Date/Time

Body

Required

Text

Id

Optional

GUID

Index

Optional

Integer

AppointmentProperties

Optional

Text

You use Id or Index mapping depending on your primary key data type. You use AppointmentProperties to save unmapped appointment properties which includes Reminder, Action, Recurrence, AllDayEvent, Label, Resource IDs, Contact IDs and CustomData (which will be explained in a bit). For most scheduling scenarios this data model fits perfectly. You simply provide the direct mappings to your data source. You can easily rename "Location" to "Room" or something, but some scenarios call for further data customization. For example, you may need to associate more data fields to each appointment. You may also want to attach a custom Business Object to each appointment. The C1Scheduler control provides flexible solutions for these kinds of scenarios. Two additional properties on each Appointment object you can access in code include: CustomData (string) The Appointment.CustomData property is serialized with other properties in the AppointmentProperties storage. If you just need a few additional data fields which can easily be saved as text you should use this property. This property is serialized into XML format and saved into the underlying datasource if the mapping for AppointmentProperties is set. The CustomData property gets saved and loaded with the appointment when users export/import data; however it is not retained when using iCal format. Tag (object) If you want to associate some business object with each appointment, and you don't need to serialize it along with the appointment, you can use the Appointment.Tag property. Since the business object is not serialized with each appointment, you must then supply some logic in the AppointmentAdded and AppointmentChanged events. In these events you look for your business object or DataRow from the Appointment key and then synchronize your business object properties or set the Tag property to your business object to use this later along with the appointment. To allow users to see and edit the custom data or business object properties, you should create a custom Appointment dialog for editing and inserting appointments. Creating a custom dialog has other benefits too: you can change the layout, style, and even use modeless dialogs rather than the default modal ones used by the control. The sample below demonstrate how to create a custom dialog and customize the data model using the two properties described above.

Sample

Creating a Custom Appointment Dialog

The "CustomDialogs" sample which installs with C1Scheduler in Studio for Silverlight includes the source code and XAML for the built-in dialogs. You can use these as a starting point for creating any custom dialog. The key thing when using CustomData or Tag to store your additional data, is that you should add bindings on your custom editor controls. In this sample we bind a TextBox to our CustomData property, and we bind two other TextBoxes to the two extra fields from our business object through the Appointment's Tag property. To customize the built-in Edit Appointment dialog, first add a new WPF or Silverlight User Control (XAML) to your project. Then you can copy the source code and XAML from the CustomDialogs sample to get started, or start from scratch. In this sample we name our user control EditAppointmentDialog.xaml. We tell the C1Scheduler control to use our custom dialog by assigning it to the EditAppointmentTemplate property.

<UserControl.Resources> local:EditAppointmentDialog/ </UserControl.Resources> ... <c1sched:C1Scheduler x:Name="sched1" EditAppointmentTemplate="{StaticResource customEditAppointmentTemplate}" />

Implementing CustomData

To fully implement usage of the CustomData property, you simply set the binding to this property on the Editor control in your dialog. For example, here we bind a TextBox to the CustomData property. Remember, this will get serialized with the appointment through the "Properties" so you must have the AppointmentProperties mapped to your data source. XAML Snippet:

That's it. Users can now modify this at run-time, save, close the application, open it again and it's there (serialized). If we were to examine the Properties field in our data source, it would look like this:

Implementing Tag

In this sample we have two extra properties on our business object (BOProperty1 and BOProperty2) which we want set for each appointment. The data source of the C1Scheduler control is our list of objects, however the control only provides direct mapping for the several properties discussed above (Subject, Location, Body, etc). We will assign our business object to the Tag property of the appointment so we can later retrieve any additional data we need. When the user adds a new appointment (i.e. when the Appointment dialog is opened for creating a new appointment) the custom business object doesn't exist yet. So first, we need to create a new instance of our object in the C1Scheduler's UserAddingAppointment event, where AppointmentBORow is our business object.

private void sched1_UserAddingAppointment(object sender, C1.Silverlight.Schedule.AppointmentActionEventArgs e) { AppointmentBORow newApp = new AppointmentBORow(); e.Appointment.Tag = newApp; }

Once the appointment is added to the scheduler, we need to update our underlying data source for the additional, unmapped properties. In the AppointmentAdded event, we can obtain the modified business object from the e.Appointment.Tag parameter. We simply take the new values from this and apply it to our data source. In this sample we have a simple FindMyAppointment method which returns the newly added business object from our data source. We can find the exact appointment added by optaining the Appointment key.

private void sched1_AppointmentAdded(object sender, C1.Silverlight.Schedule.AppointmentActionEventArgs e) { AppointmentBORow newApp = FindMyAppointment((Guid)e.Appointment.Key[0]); AppointmentBORow editedApp = e.Appointment.Tag as AppointmentBORow; if (editedApp != null) { newApp.BOProperty1 = editedApp.BOProperty1; newApp.BOProperty2 = editedApp.BOProperty2; } }

When the user edits an existing appointment, we need to fetch our custom business object from our data source and reassign it to the appointment. Remember, this is because the custom business objects are not serialized through the Tag property. We can handle this in the UserEditingAppointment event.

private void sched1_UserEditingAppointment(object sender, C1.Silverlight.Schedule.AppointmentActionEventArgs e) { AppointmentBORow myApp = FindMyAppointment((Guid)e.Appointment.Key[0]); e.Appointment.Tag = myApp; }

In the custom EditAppointmentDialog UserControl...

When editing appointments, the C1Scheduler control internally creates a copy of the appointment and puts the original into the Appointment's Tag property. This allows the user to cancel any changes or apply all changes at once after closing the dialog. So in our custom appointment dialog our business object is one level deeper, at Appointment.Tag.Tag. In the source code from our Edit Appointment dialog we have access to the original appointment, the current appointment (which could have changes) and our custom business object as shown below (note: in this sample we do not use this code, it's just shown incase you should need to know how to access your business object from in the dialog's code).

private void UserControl_Loaded(object sender, RoutedEventArgs e) { _appointment = DataContext as Appointment; Appointment _originalApp = _appointment.Tag as Appointment; //Saved copy of original AppointmentBORow _customBO = originalApp.Tag as AppointmentBORow; //Our custom business object ...

The Edit Appointment dialog also has some additional bindings to our extra properties. In the XAML template for the dialog we simply set these bindings to the properties under Tag.Tag (Remember, Tag is the original copy of the appointment, Tag.Tag is our custom object). XAML Snippet:

Download Full Sample (Silverlight 4, VS2010)

ComponentOne Product Manager Greg Lutz

Greg Lutz

comments powered by Disqus