Scheduler for WPF and Silverlight | ComponentOne
Scheduler Components and Controls / Data-centric Architecture with Silverlight / The Sample Application / Implement the Client Side / Use the Web Service to Get the Data
In This Topic
    Use the Web Service to Get the Data
    In This Topic

    We are finally ready to get the data and show it to the users. Complete the following:

    1. Open the MainPage.xaml.cs file and add the following using statements to the block at the top of the file:

      C#
      Copy Code
      using System.IO;
      using C1.Silverlight.Data;
      using Scheduler.DataService;
      using C1.Silverlight.Schedule;
      using C1.C1Schedule;
      

    2. Next, edit the page constructor as follows:

      C#
      Copy Code
      private DataSet _ds = null;
      private DataTable _dtAppointments = null;
      
      public Page()
      {
        InitializeComponent();
        // set mappings for AppointmentStorage
        // (set mapping between AppointmentStorage and Appointment table columns)
        AppointmentMappingCollection mappings = sched1.DataStorage.AppointmentStorage.Mappings;
        mappings.IdMapping.MappingName = "Id";
        mappings.Subject.MappingName = "Subject";
        mappings.Body.MappingName = "Body";
        mappings.End.MappingName = "End";
        mappings.Start.MappingName = "Start";
        mappings.Location.MappingName = "Location";
        mappings.AppointmentProperties.MappingName = "Properties";
      
        // load actual data from server
        LoadData();
      }
      
    3. Add the following code to implement the LoadData method to invoke the Web service to retrieve the data into a DataSet object, which we will then bind to the controls on the page:

      C#
      Copy Code
      DataSet _ds = null;
      void LoadData()
      {
        // Invoke Web service
        var svc = new GetDataService();
        svc.GetDataCompleted += svc_GetDataCompleted;
        svc.GetDataAsync("Appointments");
      }
      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.ReadXml(ms);
      
        // Got the data, find the table
        dtAppointments = _ds.Tables["Appointments"];
      
        // set C1Scheduler data source to the DataTable loaded from server
        sched1.DataStorage.AppointmentStorage.DataSource = _dtAppointments;
      }
      
    4. Add the following GetDataService method implementation:

      C#
      Copy Code
      // 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 = GetAbsoluteUri("DataService.asmx");
        var address = new System.ServiceModel.EndpointAddress(uri);
      
        // Return new service client
        return new DataServiceSoapClient(binding, address);
      }
      public static Uri GetAbsoluteUri(string relativeUri)
      {
        Uri uri = System.Windows.Browser.HtmlPage.Document.DocumentUri;
        string uriString = uri.AbsoluteUri;
        int ls = uriString.LastIndexOf('/');
        return new Uri(uriString.Substring(0, ls + 1) + relativeUri);
      }
      

    The GetDataService method instantiates and returns a new DataServiceSoapClient object. We don't use the default constructor because that would refer to the development environment (http://localhost and so on). It would work correctly on the development machine, but would break when the application is deployed. Also, the default constructor uses a 65k buffer that might be too small for our data transfers. The above GetDataService method implementation takes care of both issues.

    The LoadData method above instantiates the service and invokes the GetDataAsync method. When the method finishes executing, it invokes the svc_DataCompleted delegate. The delegate instantiates a DataSet object, uses the ReadXml method to de-serialize the data provided by the server, and then sets datasource for AppointmentStorage. As mappings for AppointmentStorage have been set in a Page constructor, setting the AppointmentStorage.DataSource property will bind data to the C1Scheduler control. That would be a two-way binding, so any change to _dtAppointments will be reflected in C1Scheduler and vice versa.

    Note: This is one of the most important features of the C1.Silverlight.Data DataSet class. It uses the same XML schema that ADO.NET DataSet objects use. This allows applications to serialize data on the client and de-serialize it on the server, or vice-versa. The fact that the object models are very similar also makes things substantially easier for the developer.