RadScheduler for Silverlight learning series, part 2: Loading Data Into RadScheduler from RIA Services

by Evan Hutnick | Comments 4

After reading the first part of this series, you should now have a project that is ready to wire up with events.  In summary, last time we:

  • Created a new project with RIA services enabled
  • Created a database to hold appointments
  • Threw that database into an ADO.Net Entity Data Model
  • Used aforementioned entity model in a new Domain Service Class
  • Added a RadScheduler and DomainDataSource to our Silverlight app

Now, we get to the fun part and can start wiring up some of the events we set in the last post.  The first thing that we need to do is to handle when our DomainDataSource loads its data.  In our Silverlight application we set an Appointment (from Telerik.Windows.Controls.Scheduler) observable collection to be used across the board (named myApps for future reference), but the data coming back from our DomainDataSource is coming back in SqlAppointments.  This is easy to work with, as we run a simple foreach on the data coming back as follows:

    var myAppts = e.Entities;  
 
    foreach (SqlAppointments anApp in myAppts)  
    {  
        //Make RadScheduler appointments out of Database appointments  
    } 

 

If only it were that easy! :)

We actually need to convert our appointments from SqlAppointments to regular Appointments, which we can do pretty easily:

 

    foreach (SqlAppointments anApp in myAppts)  
    {  
        Appointment newApp = new Appointment()  
        {  
            Start = anApp.Start.ToLocalTime(),  
            End = anApp.End.ToLocalTime(),  
            Subject = anApp.Subject,  
            Body = anApp.Body,  
            IsAllDayEvent = anApp.IsAllDayEvent,  
            Location = anApp.Location,  
            Url = anApp.Url,  
            UniqueId = anApp.UniqueId.ToString(),                      
        }; 

 

The next step is handling recurrence...  Now, you could go the easy way and disable recurrence, but that wouldn't make our scheduling application too powerful, now would it?  Thankfully, the RadScheduler team has provided us with RecurrencePatternHelper to come to the rescue.  This serves two purposes- first, it can convert a recurrence pattern into a serialized string for storage, and second it lets you take that string back into your application and turns it into a pattern to use for your recurrence rule. 

This brings us to a whole new topic- handling recurrence exceptions.  Yes, recurrence is a great and wonderful thing, but if you didn't have the ability to make modifications to your appointments- say, you have a daily morning appointment, but every so often one includes people from another team and you want that in the reminder.  Exceptions are another beast entirely, but not quite so difficult to deal with.  To work with this concept, I created the RecurrenceExceptionHelper class to do something very similar to what the RecurrencePatternHelper class does- it takes appointment exceptions and serializes them into a string for storage, then on the return trip it can take that string and turn it into a string of appointment exception occurrences.  I won't bore you with the details of how that works right now (I'll save that for the next post), but keep in mind it will be present in the example here so you can ignore the magic it is doing behind the scenes.

Back from that tangent, along with the recurrence pattern we need to load exceptions into the appointment so that RadScheduler knows where the abormalities are and how to show them.  Once that is complete, we add our appointments to the myApps collection and set that as the AppointmentsSource of RadScheduler, kinda like this:

        var pattern = new RecurrencePattern();  
        if (RecurrencePatternHelper.TryParseRecurrencePattern(anApp.RecurrencePattern, out pattern))  
        {  
            newApp.RecurrenceRule = new RecurrenceRule(pattern);  
 
            if (!String.IsNullOrEmpty(anApp.ExceptionAppointments))  
            {  
                List<ExceptionOccurrence> myExceptions = ExceptionHelper.RecreateExceptions(anApp.ExceptionAppointments);  
 
                foreach (ExceptionOccurrence ex in myExceptions)  
                {  
                    newApp.RecurrenceRule.AddException(ex.ExceptionDate, ex.Appointment);  
                }        
            }  
        }  
        else  
        {  
            newApp.RecurrenceRule = null;  
        }  
 
        myApps.Add(newApp);  
    }  
 
    xRadScheduler.AppointmentsSource = myApps

 

Now we've got the ability to bring appointments back from the database.  But wait, how do we save appointments to the database, edit them or delete them?  Stay tuned to part three of this series for the RadScheduler events that will pull this all together and give you your RIA-ified RadScheduler that will be the basis of the rest of this series.

Stay tuned!!

About the author

Evan Hutnick

Evan Hutnick

works as a Developer Evangelist for Telerik specializing in Silverlight and WPF in addition to being a Microsoft MVP for Silverlight. After years as a development enthusiast in .Net technologies, he has been able to excel in XAML development helping to provide samples and expertise in these cutting edge technologies. You can find him on Twitter @EvanHutnick.

4 Comments

Ben Hayat
Evan, when are you planning to release the project code? The reason I ask, is because at the beginning, you went a bit fast by declaring

var myAppts = e.Entities;

where it's not clear where the e.Entities came from!

..Ben
Evan Hutnick
Hey Ben,

In response to your first question, that comes next Tuesday my friend. :)

And sorry for the lack of explanation...

When returning the values, from my experience with using RIA services I see e.Entities as something like e.Result (if using a WCF service query when using my Linq2Sql model, for example).  e.Entities is the top level entity set being returned from the WhateverQuery you are running.

On the other hand, if we were using more complex entities (i.e., if using relational tables for storing appointments, or say we are using RIA for a RadGridView and you have Customers,  Customer.Orders), you would want to use e.AllEntities, which would contain *all* entities and not just the top level ones.  Personally speaking, I haven't played around with e.AllEntities yet since e.Entities met my needs for this project, but who knows what the future will bring.
Ben Hayat
Thanks Evan; BTW nice to have you on board!

You know, I was thinking. It would be real helpful, to have a blog that starts with high level explanation of this control, what's it does (what it doesn't), how the database should be designed to store data related to schedule, how and when data should be stored and retrieved, and where it should become incorporated into an application and etc. I think a good "Big" picture makes all the smaller items much more clear.

Tim Heuer just made a great blog about "How do you learn stuff?" and there were some great replies there. I'd like to take this opportunity to share this with Telerik team, for their blogs, especially new controls and how they should introduce them to masses. Here is the link:
http://timheuer.com/blog/archive/2009/09/03/how-do-you-want-to-learn-silverlight.aspx

Hope this helps, and don't stop these series. Maybe we'll do something together on CoverFlow after beta!
..Ben
Alex
Evan, could you explain where is the class ReccurencePatternHelper is placed?
I know there is one in silverlight 3 assembly, but as I know, I cannot reference it on server side.

Comments

  1.    
      
      
       
  2. (optional, emails won't be shown on public pages)
  3. (optional)
Read more articles by Evan Hutnick - or - read latest articles in Developer Tools
Product Families