How to enhance limited iCalendar support

8 posts, 0 answers
  1. Tinus
    Tinus avatar
    23 posts
    Member since:
    Jun 2012

    Posted 05 Aug 2010 Link to this post

    Hello,

    in my app I have to import and export iCalendar data. I do not use data binding. iCalendar format is used to persist data.

    Unfortunately the existing implementation is limited.Only a subset of the appointment properties are exported. For example resources are completely missing. Is there an "easy" way to add resources for import/export?

    A second problem is double import creating double entries instead of overwriting. Every VEVENT has a uid property which uniquely identifies the event. This should not create duplicates on import.

    Regards
    Martin
  2. Dobry Zranchev
    Admin
    Dobry Zranchev avatar
    348 posts

    Posted 06 Aug 2010 Link to this post

    Hi Tinus,

    Thank you for writing.

    1. Unfortunately, for now we do not support exporting of the resources in ICal format. We will research how we can represent in this format. You are the first to ask for this, and if more people ask for this feature we will implement it. Meanwhile, we support custom import/export. You could implement your own classes that store and load appointments to a custom format. The help is missing here, but I will prepare an example for one of next two official releases.

    2. We do not support the functionality to verify whether the item is already imported. You could remove all appointments and import the file that you want.

    Feel free to write us if you have other questions.

    Greetings,
    Dobry Zranchev
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Tinus
    Tinus avatar
    23 posts
    Member since:
    Jun 2012

    Posted 06 Aug 2010 Link to this post

    Hi Dobry,

    thanks for your feedback.

    1. I can't wait for one of next two official releases. I will have a look at the source code and try to derive  from SchedulerICalendarExporter/Importer. Maybe I can add resource support this way.

    2. Removing all appointments during import is no solution because this would prohibit to import from different sources and create a merged schedule.

    Regards
    Martin
  5. Peter
    Admin
    Peter avatar
    1148 posts

    Posted 11 Aug 2010 Link to this post

    Hello Tinus,

    Thank you for writing.

    You are able to inherit SchedulerICalendarExporter and implement custom logic in the WriteAdditionalDataForAppointment. Regarding your second question, you should take a look on VEVENT's Equals(CalObject other) function (or HasSameProperties function) which compares two CalObject objects.

    Let me know whether this helps.

    All the best,
    Peter
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  6. Tinus
    Tinus avatar
    23 posts
    Member since:
    Jun 2012

    Posted 17 Aug 2010 Link to this post

    Hi Peter,

    thanks for the hints, will keep you informed.

    Martin
  7. Tinus
    Tinus avatar
    23 posts
    Member since:
    Jun 2012

    Posted 16 Sep 2010 Link to this post

    ok, back from vacation here's my solution (I've uploaded the 2 files to code library).

    To export resources derive a new class from SchedulerICalendarExporter and override WriteAdditionalDataForAppointment.
    We need access to the resource collection of RadScheduler, so I added a new constructor:

          private readonly SchedulerResourceCollection m_Resources;

          public SchedulerICalendarExporter2(SchedulerResourceCollection resources)
             : base()
          {
             m_Resources = resources;
          }

    WriteAdditionalDataForAppointment now first calls the base class and then checks for a ResourceId. When present, a resoure string is created and added to the properties collection:

          protected override void WriteAdditionalDataForAppointment(IEvent appointment, CalObject calObject)
          {
             base.WriteAdditionalDataForAppointment(appointment, calObject);

             // new);
             if (appointment.ResourceId != null)
             {
                string resources = BuildResources(appointment.ResourceIds);
                calObject.AddProperty("RESOURCES", resources);
             }
          }

          private string BuildResources(ObservableCollection<EventId> resourceIds)
          {
             string res = string.Empty;

             foreach (EventId resourceId in resourceIds)
             {
                string resource = m_Resources.GetById(resourceId.KeyValue).Name;
                if (res == string.Empty)
                   res += resource;
                else
                {
                   res += "," + resource;
                }
             }

             return res;
          }

    To use the new export create an instance of the new export and use the constructor to assign the resource collection.

             ISchedulerExporter exporter = new SchedulerICalendarExporter2(radScheduler1.Resources);
            using (FileStream f = new FileStream("export.ics"FileMode.Create))
             {
                radScheduler1.Export(f, exporter);
             }

    Importing resources from iCal is done in a very similar way. Again we derive from SchedulerICalendarImporter and need a constructor which provides the resource collection:

          private SchedulerResourceCollection m_Resources;

          public SchedulerICalendarImporter2(SchedulerResourceCollection resources)
             : base()
          {
             m_Resources = resources;
          }

    Here we override ApplyAdditionalData and add back our resoure Ids.

          protected override void ApplyAdditionalData(IEvent appointment, CalObject calObject)
          {
             base.ApplyAdditionalData(appointment, calObject);

             CalProperty prop = calObject["RESOURCES"];
             if (prop != null)
             {
                AddResourceIds(prop, appointment);
             }
          }

          private void AddResourceIds(CalProperty prop, IEvent appointment)
          {
             string[] resources = CalProperty.ToText(prop).Split(new[] { ';'',' }, StringSplitOptions.RemoveEmptyEntries);

             foreach (string resource in resources)
             {
                if (m_Resources.GetById(resource) == null)
                   m_Resources.Add(new Resource(resourceresource));
                appointment.ResourceIds.Add(new EventId(resource));
             }
          }

    And finally I solved my duplication problem by multiple imports. Override GetAppointments and rebuild the collection after creating a unique dictionary:

          /// <summary>
          /// Remove duplicates based on UniqueId
          /// </summary>
          /// <exception cref="CalendarParseException"><c>CalendarParseException</c>.</exception>
          protected override void GetAppointments(CalObject calendar, ICollection<IEvent> collection)
          {
             base.GetAppointments(calendar, collection);

             Dictionary<EventIdIEvent> dictionary = new Dictionary<EventIdIEvent>();
             foreach (IEvent ievent in collection)
             {
                dictionary[ievent.UniqueId] = ievent;
             }

             collection.Clear();
             foreach (IEvent iEvent in dictionary.Values)
                collection.Add(iEvent);
          }

    Regards
    Martin
  8. Stefan
    Admin
    Stefan avatar
    2891 posts

    Posted 21 Sep 2010 Link to this post

    Hello Tinus,

    Please find the full code library here: Import and export iCalendar data with resources

    Best wishes,
    Stefan
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  9. jdgoulden
    jdgoulden avatar
    20 posts
    Member since:
    Nov 2006

    Posted 15 Oct 2010 Link to this post

    Thank you for the code example, this was exactly what I was looking to do as well
Back to Top
UI for WinForms is Visual Studio 2017 Ready