Scheduler for WPF and Silverlight | ComponentOne
Scheduler for Silverlight Tutorials / Creating a Multi-User Schedule / Step 3 of 4: Adding the Code to your Application
In This Topic
    Step 3 of 4: Adding the Code to your Application
    In This Topic

    In this step you will add the code to control your application.

    1. Right-click your application and select View Code from the list.
    2. Add the following statements to the Import or using statements at the top of the page:

      Visual Basic
      Copy Code
      Imports C1.Silverlight.Schedule
      Imports System.Collections.Specialized
      Imports C1.C1Schedule
      Imports C1.Silverlight.Data
      Imports System.IO
      Imports System.Windows.Data
      Imports System.Globalization
      Imports MultiUser.DataService
      

      C#
      Copy Code
      using C1.Silverlight.Schedule;
      using System.Collections.Specialized;
      using C1.C1Schedule;
      using C1.Silverlight.Data;
      using MultiUser.DataService;
      using System.IO;
      using System.Windows.Data;
      using System.Globalization;
      using System.ServiceModel;
      

    3. Insert the following code below the initial class statement:

      Visual Basic
      Copy Code
      Private _ds As DataSet = Nothing
      Private _dtAppointments As DataTable = Nothing
      Private _dtEmployees As DataTable = Nothing
      Private _dtCustomers As DataTable = Nothing
      

      C#
      Copy Code
      private DataSet _ds = null;
      private DataTable _dtAppointments = null;
      private DataTable _dtEmployees = null;
      private DataTable _dtCustomers = null;
      

    4. Add the following code directly underneath the InitializeComponent() method call to set C1Scheduler.ReminderFire and Scheduler.GroupItems.CollectionChanged event handlers:

      Visual Basic
      Copy Code
      AddHandler Scheduler.ReminderFire, AddressOf scheduler_ReminderFire
      AddHandler Scheduler.GroupItems.CollectionChanged, GroupItems_CollectionChanged
      

      C#
      Copy Code
      Scheduler.ReminderFire += new EventHandler<ReminderActionEventArgs>(scheduler_ReminderFire);
      Scheduler.GroupItems.CollectionChanged += new NotifyCollectionChangedEventHandler(GroupItems_CollectionChanged);
      

    5. Set the mappings for the AppointmentStorage, OwnerStorage, and ContactStorage for the Scheduler:

      Visual Basic
      Copy Code
      ' set mappings for the AppointmentStorages
              Dim storage As AppointmentStorage = Scheduler.DataStorage.AppointmentStorage
              storage.Mappings.AppointmentProperties.MappingName = "Properties"
              storage.Mappings.Body.MappingName = "Description"
              storage.Mappings.[End].MappingName = "End"
              storage.Mappings.IdMapping.MappingName = "AppointmentId"
              storage.Mappings.Location.MappingName = "Location"
              storage.Mappings.Start.MappingName = "Start"
              storage.Mappings.Subject.MappingName = "Subject"
              storage.Mappings.OwnerIndexMapping.MappingName = "Owner"
      
              ' set mappings for the OwnerStorage
              Dim ownerStorage As ContactStorage = Scheduler.DataStorage.OwnerStorage
              AddHandler DirectCast(ownerStorage.Contacts, INotifyCollectionChanged).CollectionChanged, New NotifyCollectionChangedEventHandler(AddressOf Owners_CollectionChanged)
              ownerStorage.Mappings.IndexMapping.MappingName = "EmployeeId"
              ownerStorage.Mappings.TextMapping.MappingName = "FirstName"
      
              ' set mappings for the ContactStorage
              Dim cntStorage As ContactStorage = Scheduler.DataStorage.ContactStorage
              AddHandler DirectCast(cntStorage.Contacts, INotifyCollectionChanged).CollectionChanged, New NotifyCollectionChangedEventHandler(AddressOf Contacts_CollectionChanged)
              cntStorage.Mappings.IdMapping.MappingName = "CustomerId"
              cntStorage.Mappings.TextMapping.MappingName = "CompanyName"
      
              ' load data from server
              LoadData()
      

      C#
      Copy Code
      // set mappings for the AppointmentStorages
                  AppointmentStorage storage = Scheduler.DataStorage.AppointmentStorage;
                  storage.Mappings.AppointmentProperties.MappingName = "Properties";
                  storage.Mappings.Body.MappingName = "Description";
                  storage.Mappings.End.MappingName = "End";
                  storage.Mappings.IdMapping.MappingName = "AppointmentId";
                  storage.Mappings.Location.MappingName = "Location";
                  storage.Mappings.Start.MappingName = "Start";
                  storage.Mappings.Subject.MappingName = "Subject";
                  storage.Mappings.OwnerIndexMapping.MappingName = "Owner";
      
                  // set mappings for the OwnerStorage
                  ContactStorage ownerStorage = Scheduler.DataStorage.OwnerStorage;
                  ((INotifyCollectionChanged)ownerStorage.Contacts).CollectionChanged += new NotifyCollectionChangedEventHandler(Owners_CollectionChanged);
                  ownerStorage.Mappings.IndexMapping.MappingName = "EmployeeId";
                  ownerStorage.Mappings.TextMapping.MappingName = "FirstName";
      
                  // set mappings for the ContactStorage
                  ContactStorage cntStorage = Scheduler.DataStorage.ContactStorage;
                  ((INotifyCollectionChanged)cntStorage.Contacts).CollectionChanged += new NotifyCollectionChangedEventHandler(Contacts_CollectionChanged);
                  cntStorage.Mappings.IdMapping.MappingName = "CustomerId";
                  cntStorage.Mappings.TextMapping.MappingName = "CompanyName";
      
                  // load data from server
                  LoadData();
      

    6. Add the following code to handle the GroupItems_CollectionChanged event:

      Visual Basic
      Copy Code
      Private Sub GroupItems_CollectionChanged(sender As Object, e As NotifyCollectionChangedEventArgs)
              For Each group As SchedulerGroupItem In Scheduler.GroupItems
                  If group.Owner IsNot Nothing Then
                      ' set SchedulerGroupItem.Tag property to the data row. That allows to use data row fields in xaml for binding
                      Dim index As Integer = CInt(group.Owner.Key(0))
                      group.Tag = _dtEmployees.Rows.Find(index)
                  End If
              Next
          End Sub
      

      C#
      Copy Code
      void GroupItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
              {
                  foreach (SchedulerGroupItem group in Scheduler.GroupItems)
                  {
                      if (group.Owner != null)
                      {
                          // set SchedulerGroupItem.Tag property to the data row. That allows to use data row fields in xaml for binding
                          int index = (int)group.Owner.Key[0];
                          group.Tag = _dtEmployees.Rows.Find(index);
                      }
                  }
              }
      

    7. Use the following code to handle the Owners_CollectionChanged event:        

      Visual Basic
      Copy Code
      Private Sub Owners_CollectionChanged(sender As Object, e As NotifyCollectionChangedEventArgs)
              If e.Action = NotifyCollectionChangedAction.Add Then
                  For Each cnt As Contact In e.NewItems
                      Dim row As DataRow = _dtEmployees.Rows.Find(cnt.Key(0))
                      If row IsNot Nothing Then
                          ' set Contact.MenuCaption to the FirstName + LastName string
                          cnt.MenuCaption = row("FirstName").ToString() & " " & row("LastName").ToString()
                      End If
                  Next
              End If
          End Sub
      

      C#
      Copy Code
      void Owners_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
              {
                  if (e.Action == NotifyCollectionChangedAction.Add)
                  {
                      foreach (Contact cnt in e.NewItems)
                      {
                          DataRow row = _dtEmployees.Rows.Find(cnt.Key[0]);
                          if (row != null)
                          {
                              // set Contact.MenuCaption to the FirstName + LastName string
                              cnt.MenuCaption = row["FirstName"].ToString() + " " + row["LastName"].ToString();
                          }
                      }
                  }
              }
      

    8. Insert the code below to handle the Contacts_CollectionChanged event:

      Visual Basic
      Copy Code
      Private Sub Contacts_CollectionChanged(sender As Object, e As NotifyCollectionChangedEventArgs)
              If e.Action = NotifyCollectionChangedAction.Add Then
                  For Each cnt As Contact In e.NewItems
                      Dim row As DataRow = _dtCustomers.Rows.Find(cnt.Key(0))
                      If row IsNot Nothing Then
                          ' set Contact.MenuCaption to the CompanyName + Contactname string
                          cnt.MenuCaption = row("CompanyName").ToString() & " (" & row("ContactName").ToString() & ")"
                      End If
                  Next
              End If
          End Sub
      

      C#
      Copy Code
      void Contacts_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
              {
                  if (e.Action == NotifyCollectionChangedAction.Add)
                  {
                      foreach (Contact cnt in e.NewItems)
                      {
                          DataRow row = _dtCustomers.Rows.Find(cnt.Key[0]);
                          if (row != null)
                          {
                              // set Contact.MenuCaption to the CompanyName + Contactname string
                              cnt.MenuCaption = row["CompanyName"].ToString() + " (" + row["ContactName"].ToString() + ")";
                          }
                      }
                  }
              }
      

    9. Add an event handler to prevent showing reminders:        

      Visual Basic
      Copy Code
      ' prevent showing reminders
      
          Private Sub scheduler_ReminderFire(sender As Object, e As ReminderActionEventArgs)
      
              e.Handled = True
      
          End Sub
      

      C#
      Copy Code
      // prevent showing reminders
      
              private void scheduler_ReminderFire(object sender, ReminderActionEventArgs e)
      
              {
      
                  e.Handled = true;
      
              }
      

    10. Insert the following region to handle loading data:        

      Visual Basic
      Copy Code
      #Region "** loading data"
      
          ' Get data service relative to current host/domain
          Private Function GetDataService() As DataServiceSoapClient
      
              ' Increase buffer size
              Dim binding = New System.ServiceModel.BasicHttpBinding()
              binding.MaxReceivedMessageSize = 2147483647
      
              ' int.MaxValue
              binding.MaxBufferSize = 2147483647
      
              ' int.MaxValue
              ' Get absolute service address
      
              Dim uri As Uri = C1.Silverlight.Extensions.GetAbsoluteUri("DataService.asmx")
              Dim address = New System.ServiceModel.EndpointAddress(uri)
      
              ' Return new service client
              Return New DataServiceSoapClient(binding, address)
          End Function
       
          Private Sub LoadData()
              ' Invoke Web service
              Dim svc = GetDataService()
              AddHandler svc.GetDataCompleted, AddressOf svc_GetDataCompleted
              svc.GetDataAsync("Appointments,Employees,Customers")
          End Sub
       
          Private Sub svc_GetDataCompleted(sender As Object, e As GetDataCompletedEventArgs)
              ' Handle errors
              If e.[Error] IsNot Nothing Then
                  tbStatus.Text = "Error downloading data..."
                  Return
              End If
      
              ' Parse data stream from server (DataSet as XML)
              tbStatus.Text = String.Format("Got data, {0:n0} kBytes", e.Result.Length / 1024)
       
              Dim ms = New MemoryStream(e.Result)
              _ds = New DataSet()
              _ds.EnforceConstraints = False
              _ds.ReadXml(ms)
              _ds.EnforceConstraints = True
      
              ' Got the data, find the table
              _dtAppointments = _ds.Tables("Appointments")
              _dtEmployees = _ds.Tables("Employees")
              _dtCustomers = _ds.Tables("Customers")
      
              ' set C1Scheduler data source to the DataTable loaded from server
              Scheduler.DataStorage.AppointmentStorage.DataSource = _dtAppointments
              Scheduler.DataStorage.ContactStorage.DataSource = _dtCustomers
              Scheduler.DataStorage.OwnerStorage.DataSource = _dtEmployees
          End Sub
      #End Region
      

      C#
      Copy Code
      #region ** loading data
              // Get data service relative to current host/domain
              DataServiceSoapClient GetDataService()
              {
                  // Increase buffer size
                  var binding = new System.ServiceModel.BasicHttpBinding();
                  binding.MaxReceivedMessageSize = 2147483647; // int.MaxValue
                  binding.MaxBufferSize = 2147483647; // int.MaxValue
      
                  // Get absolute service address
                  Uri uri = C1.Silverlight.Extensions.GetAbsoluteUri("DataService.asmx");
                  var address = new System.ServiceModel.EndpointAddress(uri);
      
                  // Return new service client
                  return new DataServiceSoapClient(binding, address);
              }
      
              void LoadData()
              {
                  // Invoke Web service
                  var svc = GetDataService();
                  svc.GetDataCompleted += svc_GetDataCompleted;
                  svc.GetDataAsync("Appointments,Employees,Customers");
              }
       
              void svc_GetDataCompleted(object sender, GetDataCompletedEventArgs e)
              {
                  // Handle errors
                  if (e.Error != null)
                  {
                      tbStatus.Text = "Error downloading data...";
                      return;
                  }
      
                  // Parse data stream from server (DataSet as XML)
                  tbStatus.Text = string.Format(
                    "Got data, {0:n0} kBytes", e.Result.Length / 1024);
       
                  var ms = new MemoryStream(e.Result);
                  _ds = new DataSet();
                  _ds.EnforceConstraints = false;
                  _ds.ReadXml(ms);
                  _ds.EnforceConstraints = true;
       
                  // Got the data, find the table
                  _dtAppointments = _ds.Tables["Appointments"];
                  _dtEmployees = _ds.Tables["Employees"];
                  _dtCustomers = _ds.Tables["Customers"];
      
                  // set C1Scheduler data source to the DataTable loaded from server
                  Scheduler.DataStorage.AppointmentStorage.DataSource = _dtAppointments;
                  Scheduler.DataStorage.ContactStorage.DataSource = _dtCustomers;
                  Scheduler.DataStorage.OwnerStorage.DataSource = _dtEmployees;
              }
              #endregion
      

    11. The following code handles the Scheduler_StyleChanged event:

      Visual Basic
      Copy Code
      Private Sub Scheduler_StyleChanged(sender As Object, e As RoutedEventArgs)
              If Scheduler.Style Is Scheduler.TimeLineStyle Then
                  ' update group header (use different headers for TimeLine and other views)
                  Scheduler.GroupHeaderTemplate = DirectCast(Resources("myCustomTimeLineGroupHeaderTemplate"), DataTemplate)
                  btnTimeLine.IsChecked = True
              Else
                  ' update group header (use different headers for TimeLine and other views)
                  Scheduler.GroupHeaderTemplate = DirectCast(Resources("myCustomGroupHeaderTemplate"), DataTemplate)
                  ' update toolbar buttons state according to the current C1Scheduler view
                  If Scheduler.Style Is Scheduler.WorkingWeekStyle Then
                      btnWorkWeek.IsChecked = True
                  ElseIf Scheduler.Style Is Scheduler.WeekStyle Then
                      btnWeek.IsChecked = True
                  ElseIf Scheduler.Style Is Scheduler.MonthStyle Then
                      btnMonth.IsChecked = True
                  Else
                      btnDay.IsChecked = True
                  End If
              End If
          End Sub
      

      C#
      Copy Code
      private void Scheduler_StyleChanged(object sender, RoutedEventArgs e)
              {
                  if (Scheduler.Style == Scheduler.TimeLineStyle)
                  {
                      // update group header (use different headers for TimeLine and other views)
                      Scheduler.GroupHeaderTemplate = (DataTemplate)Resources["myCustomTimeLineGroupHeaderTemplate"];
                      btnTimeLine.IsChecked = true;
                  }
                  else
                  {
                      // update group header (use different headers for TimeLine and other views)
                      Scheduler.GroupHeaderTemplate = (DataTemplate)Resources["myCustomGroupHeaderTemplate"];
                      // update toolbar buttons state according to the current C1Scheduler view
                      if (Scheduler.Style == Scheduler.WorkingWeekStyle)
                      {
                          btnWorkWeek.IsChecked = true;
                      }
                      else if (Scheduler.Style == Scheduler.WeekStyle)
                      {
                          btnWeek.IsChecked = true;
                      }
                      else if (Scheduler.Style == Scheduler.MonthStyle)
                      {
                          btnMonth.IsChecked = true;
                      }
                      else
                      {
                          btnDay.IsChecked = true;
                      }
                  }
              }
      

    12. The last section of code to insert is the code that creates the BooleanToVisibilityConverter:        

      Visual Basic
      Copy Code
      Public Class BooleanToVisibilityConverter
              Implements IValueConverter
              Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object
                  If TypeOf value Is [Boolean] Then
                      Return If(CBool(value), Visibility.Visible, Visibility.Collapsed)
                  End If
                  Return value
              End Function
              Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object
                  Throw New NotImplementedException()
              End Function
              Public Function Convert1(value As Object, targetType As System.Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
                  Return value
              End Function
              Public Function ConvertBack1(value As Object, targetType As System.Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
                  Return value
              End Function
          End Class
      End Class
      

      C#
      Copy Code
      public class BooleanToVisibilityConverter : IValueConverter
              {
                  public object Convert(object value, Type targetType, object parameter,
                                        CultureInfo culture)
                  {
                      if (value is Boolean)
                      {
                          return ((bool)value) ? Visibility.Visible : Visibility.Collapsed;
                      }
                      return value;
                  }
                  public object ConvertBack(object value, Type targetType, object parameter,
                                            CultureInfo culture)
                  {
                      throw new NotImplementedException();
                  }
              }
          }
      }