RadControls for WinForms

This walkthrough will cover creating and binding RadScheduler to a data source in a step-by-step manner

Note

Another example of binding RadScheduler is available in our RadControls for WinForms Step-by-step Tutorial

The database

RadScheduler has a very flexible binding system which can cover various binding scenarios. Most of them are covered in the next articles. Here we will cover the scenario with binding to a database in which appointments and resources are in a many-to-many relation. A sample database ships with our products and can be found under [Your installation directory]\Examples\DataSources\SchedulerData.mdb. By default the installation directory is C:\Program Files\Telerik\RadControls for WinForms [version]

The following screen shot demonstrates the schema of the database.

scheduler-data-binding-data-binding-walkthrough 001

Binding the Scheduler

Let’s assume you have added a RadScheduler to your form and you want to bind it to a data source. To do so you must first create and set up a SchedulerBindingDataSource instance. SchedulerBindingDataSet is a component and is available in your toolbox. To setup a SchedulerBindingDataSource, follow these steps:

  1. Add a SchedulerBindingDataSource from the Toolbox to the form.
  2. In the Properties window, open the EventProvider property. Drop down the DataSource sub-property list and select Add Project DataSource... This step will display the Data Source Configuration Wizard dialog.

    scheduler-data-binding-data-binding-walkthrough 002

  3. Complete this wizard by choosing Access Database File connection and selecting the sample database located under the \Examples\DataSources directory. This will create a DataSet component and add it to the component tray below the form designer.

    scheduler-data-binding-data-binding-walkthrough 003

  4. Click the "SchedulerDataDataSet" Smart Tag and select Edit in Dataset Designer. Add a relation between the Appointments and AppointmentsResources tables and name it "Appointments_AppointmentsResources". Make the "Key Columns" entry be "ID" from the Appointments table and set "Foreign Key Columns" from the AppointmentsResources table to "AppointmentID".

    scheduler-data-binding-data-binding-walkthrough 004

  5. When you create a dataset from the MS Access database, several properties of the auto number fields are wrongly set. Please, set these as in the right (correct) version below:

    scheduler-data-binding-data-binding-walkthrough 005

  6. Build the project. This step will create several useful adapter components that we will use later to fill the dataset.

    scheduler-data-binding-data-binding-walkthrough 006

Mapping the properties

In order to map the fields of your data source to the correct properties of scheduler’s objects, you need to setup two mapping info instances: one of type AppointmentMappingInfo and one of type ResourceMappingInfo. You can do this either through code or in the Visual Studio designer.

To setup appointment mapping at design time, click the Edit Appointment Mapping button in the smart tag menu of your SchedulerBindingDataSource instance. To edit the resource mapping, click the Edit Resource Mapping button.

scheduler-data-binding-data-binding-walkthrough 007

When you do so, a dialog will appear letting you choose the field of the data source which should be mapped to the corresponding appointment/resource property.

Note

The data source fields should be set prior editing the mapping in order to get automatically populated with data source fields drop downs.

Note

The Resources property of the AppointmentMappingInfo should be set with the name of the relation that connects the Appointments and the AppointmentsResources tables. The ResourceId property should be set with the name of the column in the AppointmentsResources table that holds the id of the resource.

Programatically mapping

In order to programatically map the fields of your data source to the correct properties of scheduler’s objects, you need to setup two mapping info instances: one of type AppointmentMappingInfo and one of type ResourceMappingInfo and assign them to the SchedulerBindingDataSource instance as it is demonstrated below.

Copy[C#]
AppointmentMappingInfo appointmentMappingInfo = new AppointmentMappingInfo();
appointmentMappingInfo.BackgroundId = "BackgroundID";
appointmentMappingInfo.Description = "Description";
appointmentMappingInfo.End = "End";
appointmentMappingInfo.Location = "Location";
appointmentMappingInfo.MasterEventId = "ParentID";
appointmentMappingInfo.RecurrenceRule = "RecurrenceRule";
appointmentMappingInfo.ResourceId = "ResourceID";
appointmentMappingInfo.Resources = "AppointmentsAppointmentsResources";
appointmentMappingInfo.Start = "Start";
appointmentMappingInfo.StatusId = "StatusID";
appointmentMappingInfo.Summary = "Summary";
schedulerBindingDataSource1.EventProvider.Mapping = appointmentMappingInfo;

ResourceMappingInfo resourceMappingInfo = new ResourceMappingInfo();
resourceMappingInfo.Id = "ID";
resourceMappingInfo.Name = "ResourceName";
this.schedulerBindingDataSource1.ResourceProvider.Mapping = resourceMappingInfo;
Copy[VB.NET]
Dim appointmentMappingInfo As New AppointmentMappingInfo()
appointmentMappingInfo.BackgroundId = "BackgroundID"
appointmentMappingInfo.Description = "Description"
appointmentMappingInfo.[End] = "End"
appointmentMappingInfo.Location = "Location"
appointmentMappingInfo.MasterEventId = "ParentID"
appointmentMappingInfo.RecurrenceRule = "RecurrenceRule"
appointmentMappingInfo.ResourceId = "ResourceID"
appointmentMappingInfo.Resources = "AppointmentsAppointmentsResources"
appointmentMappingInfo.Start = "Start"
appointmentMappingInfo.StatusId = "StatusID"
appointmentMappingInfo.Summary = "Summary"
SchedulerBindingDataSource1.EventProvider.Mapping = appointmentMappingInfo

Dim resourceMappingInfo As New ResourceMappingInfo()
resourceMappingInfo.Id = "ID"
resourceMappingInfo.Name = "ResourceName"
Me.SchedulerBindingDataSource1.ResourceProvider.Mapping = resourceMappingInfo

Retrieving the data

To retrieve the data, first we need to fill the data set:

Copy[C#]
this.resourcesTableAdapter.Fill(this.schedulerDataDataSet.Resources);
this.appointmentsResourcesTableAdapter.Fill(this.schedulerDataDataSet.AppointmentsResources);
this.appointmentsTableAdapter.Fill(this.schedulerDataDataSet.Appointments);
Copy[VB.NET]
Me.resourcesTableAdapter.Fill(Me.schedulerDataDataSet.Resources)
Me.appointmentsResourcesTableAdapter.Fill(Me.schedulerDataDataSet.AppointmentsResources)
Me.AppointmentsTableAdapter.Fill(Me.SchedulerDataDataSet.Appointments)
Note

You should fill the tables in the exact same order if you have already set the DataSource property of RadScheduler. Alternatively, you can just call the DataBind method of RadScheduler after you fill the tables.

Now we need to assign the Appointments and Resources tables from the data set to our SchedulerBindingDataSource (the following can also be set at design time through the Smart Tag of your SchedulerBindingDataSource instance as you can see on the previous image):

Copy[C#]
schedulerBindingDataSource1.ResourceProvider.DataSource = schedulerDataDataSet.Resources;
schedulerBindingDataSource1.EventProvider.DataSource = schedulerDataDataSet.Appointments;
Copy[VB.NET]
SchedulerBindingDataSource1.ResourceProvider.DataSource = SchedulerDataDataSet.Resources
SchedulerBindingDataSource1.EventProvider.DataSource = SchedulerDataDataSet.Appointments

Finally, we assign our SchedulerBindingDataSource instance to RadScheduler as its DataSource. This can be achieved either through the Smart Tag of RadScheduler or via code:

scheduler-data-binding-data-binding-walkthrough 008

Copy[C#]
radScheduler1.DataSource = schedulerBindingDataSource1;
Copy[VB.NET]
RadScheduler1.DataSource = SchedulerBindingDataSource1
Note

If the above steps are not performed in the same order, RadScheduler might not display the appointments. In this case you can try calling the DataBind method of RadScheduler or the Rebind method of SchedulerBindingDataSource.

Updating the database

Add the following code to the Click event handler for an "Update" button, which will update the data source. (for more information on saving data, see MSDN: How to: Update Data by Using a TableAdapter )

Copy[C#]
private void btnUpdate_Click(object sender, EventArgs e)
{
    appointmentsResourcesTableAdapter.Adapter.AcceptChangesDuringUpdate = false;
    SchedulerDataDataSet.AppointmentsResourcesDataTable deletedChildRecords =
                    this.schedulerDataDataSet.AppointmentsResources.GetChanges(DataRowState.Deleted)
                    as SchedulerDataDataSet.AppointmentsResourcesDataTable;
    SchedulerDataDataSet.AppointmentsResourcesDataTable newChildRecords =
                    this.schedulerDataDataSet.AppointmentsResources.GetChanges(DataRowState.Added)
                    as SchedulerDataDataSet.AppointmentsResourcesDataTable;
    SchedulerDataDataSet.AppointmentsResourcesDataTable modifiedChildRecords =
                    this.schedulerDataDataSet.AppointmentsResources.GetChanges(DataRowState.Modified)
                    as SchedulerDataDataSet.AppointmentsResourcesDataTable;
    try
    {
        if (deletedChildRecords != null)
        {
            appointmentsResourcesTableAdapter.Update(deletedChildRecords);
        }
        appointmentsTableAdapter.Update(this.schedulerDataDataSet.Appointments);
        if (newChildRecords != null)
        {
            appointmentsResourcesTableAdapter.Update(newChildRecords);
        }
        if (modifiedChildRecords != null)
        {
            appointmentsResourcesTableAdapter.Update(modifiedChildRecords);
        }
        this.schedulerDataDataSet.AcceptChanges();
    }
    catch (Exception ex)
    {
        MessageBox.Show(string.Format("An error occurred during the update process:\n{0}", ex.Message));
    }
    finally
    {
        if (deletedChildRecords != null)
        {
            deletedChildRecords.Dispose();
        }
        if (newChildRecords != null)
        {
            newChildRecords.Dispose();
        }
        if (modifiedChildRecords != null)
        {
            modifiedChildRecords.Dispose();
        }
    }
    lblStatus.Text = "Updated scheduler at " + DateTime.Now.ToString();
}
Copy[VB.NET]
Private Sub btnUpdate_Click(ByVal sender As Object, ByVal e As EventArgs)
    appointmentsResourcesTableAdapter.Adapter.AcceptChangesDuringUpdate = False
    Dim deletedChildRecords As SchedulerDataDataSet.AppointmentsResourcesDataTable = TryCast(Me.schedulerDataDataSet.AppointmentsResources.GetChanges(DataRowState.Deleted), SchedulerDataDataSet.AppointmentsResourcesDataTable)
    Dim newChildRecords As SchedulerDataDataSet.AppointmentsResourcesDataTable = TryCast(Me.schedulerDataDataSet.AppointmentsResources.GetChanges(DataRowState.Added), SchedulerDataDataSet.AppointmentsResourcesDataTable)
    Dim modifiedChildRecords As SchedulerDataDataSet.AppointmentsResourcesDataTable = TryCast(Me.schedulerDataDataSet.AppointmentsResources.GetChanges(DataRowState.Modified), SchedulerDataDataSet.AppointmentsResourcesDataTable)
    Try
        If deletedChildRecords IsNot Nothing Then
            appointmentsResourcesTableAdapter.Update(deletedChildRecords)
        End If
        appointmentsTableAdapter.Update(Me.schedulerDataDataSet.Appointments)
        If newChildRecords IsNot Nothing Then
            appointmentsResourcesTableAdapter.Update(newChildRecords)
        End If
        If modifiedChildRecords IsNot Nothing Then
            appointmentsResourcesTableAdapter.Update(modifiedChildRecords)
        End If
        Me.schedulerDataDataSet.AcceptChanges()
    Catch ex As Exception
        MessageBox.Show(String.Format("An error occurred during the update process:" & vbLf & "{0}", ex.Message))
    Finally
        If deletedChildRecords IsNot Nothing Then
            deletedChildRecords.Dispose()
        End If
        If newChildRecords IsNot Nothing Then
            newChildRecords.Dispose()
        End If
        If modifiedChildRecords IsNot Nothing Then
            modifiedChildRecords.Dispose()
        End If
    End Try
    lblStatus.Text = "Updated scheduler at " & Date.Now.ToString()
End Sub

scheduler-data-binding-data-binding-walkthrough 009