Hi,
I need to add an icon to the entries displayed in the calendar. I actually want to display the recurrence icon - I am implementing my own recurrence algorithm in SQL so don't use the inbuilt mechanism, however I want to show the recurrence icon in applicable entries.
I initially though I might be able to set a flag on the appointments to have them display the inbuilt icon, but without actually generating any recurrent entries, but the properties I was looking at are read only. :( So I am now thinking that I probably need to use a creation or draw filter, but I have no idea which elements I need to look for or modify, and I can't get the element viewer to work with my user control (hosted in a native app), so any help would be appreciated.
Thanks,
Brian
Hello Satoshi,
Thank you for contacting Infragistics Support.
In order to add an icon to an appointment you may set Image property of appointment appearance. You may use code like thid:
this.ultraCalendarInfo1.Appointments[i].Appearance.Image = image;
Please note this will add an image exactly where occurrence icon appears.
Please check attached sample solution and let me know if this is what you are looking for or if I am missing something.
Hi Milko,
Thanks for the quick response. I didn't realize that the image in Appearance was for the recurrence icon, and I have already used this to show a different icon for my various calendar item types, so I can't use it for the recurrence icon. I also thought that the recurrence icon would show on the right hand side, as it does in Outlook, so I have implemented a creation filter to add an image on the top right hand corner, it's not perfect as it will sit on top of the text if the item is too small, but it does work, and will probably do for now. When loading, I set the RecurrenceId property of the appointment to a GUID of zero if the item is not recurrent, all 1s if it is, and all 2s if it is recurrent and has been edited, than in the filter I display the appropriate icon, or none if it's not recurrent.
class AddIconFilter : IUIElementCreationFilter { #region IUIElementCreationFilter Members public void AfterCreateChildElements(UIElement parent) { Appointment appt = null; Size margin = new Size(); if (parent is Infragistics.Win.UltraWinSchedule.DayView.AppointmentUIElement) { Infragistics.Win.UltraWinSchedule.DayView.AppointmentUIElement elem = parent as Infragistics.Win.UltraWinSchedule.DayView.AppointmentUIElement; appt = elem.SelectableItem as Appointment; margin = new Size(8, 4); } else if (parent is Infragistics.Win.UltraWinSchedule.MonthViewSingle.AppointmentUIElement) { Infragistics.Win.UltraWinSchedule.MonthViewSingle.AppointmentUIElement elem = parent as Infragistics.Win.UltraWinSchedule.MonthViewSingle.AppointmentUIElement; appt = elem.SelectableItem as Appointment; margin = new Size(8, 0); } else if (parent is Infragistics.Win.UltraWinSchedule.TimelineView.AppointmentUIElement) { Infragistics.Win.UltraWinSchedule.TimelineView.AppointmentUIElement elem = parent as Infragistics.Win.UltraWinSchedule.TimelineView.AppointmentUIElement; appt = elem.SelectableItem as Appointment; margin = new Size(8, 0); } AddIconIfRequired(parent, appt, margin); } public bool BeforeCreateChildElements(UIElement parent) { return false; } #endregion #region Helpers void AddIconIfRequired(UIElement parent, Appointment appt, Size margin) { if (appt != null) { if (appt.RecurrenceId.CompareTo(FrmCalendar._recurrenceNoneGuid) != 0) { Image img = appt.RecurrenceId.CompareTo(FrmCalendar._recurrenceRootGuid) == 0 ? Properties.Resources.Recurring : Properties.Resources.RecurringEdit; ImageUIElement recurrenceIcon = new ImageUIElement(parent, img); Point ptIcon = new Point(Math.Max(parent.Rect.Right - img.Size.Width - margin.Width, 0), parent.Rect.Top + margin.Height); recurrenceIcon.Rect = new System.Drawing.Rectangle(ptIcon, new Size(16, 16)); parent.ChildElements.Add(recurrenceIcon); } } } #endregion }
It would be nice if it didn't overwrite the text, so I will probably look at trying to resize the text part to avoid this, and if you have any pointers for doing this that would be useful.
Hi Milko.
That tweak has solved my issue with the icon being displayed beyond the left edge in the Timeline view, and generally it behaves better when resized.
Thanks for the help,
Hello Brian,
Thank you for your feedback.
You are on the right way. In order to check if your recurrence icon should be added to an appointment you may check if there is enough space for one. You may use code like this:
if (prevSibling.Rect.Width - margin.Width > this.imageSized.Width)
{
recurrenceIcon.Rect = new Rectangle(ptIcon, new Size(icon.Size.Width, icon.Size.Height));
parent.ChildElements.Add(recurrenceIcon);
}
Please find attached a sample solution implementing your Creation Filter with this addition.
Please let me know if you have any additional questions.
I tweaked it to resize the text block too, so that the icon doesn't overlap, which works fine for most scenarios, but when displayed in a timeline the icon can be drawn to the left of the item when the size is too small to fit anything on. Not sure why this is the case, but for now I can live with it.
class AddIconFilter : IUIElementCreationFilter { #region IUIElementCreationFilter Members public void AfterCreateChildElements(UIElement parent) { Appointment appt = null; Size margin = new Size(); UIElement prevSibling = null; if (parent is Infragistics.Win.UltraWinSchedule.DayView.AppointmentUIElement) { Infragistics.Win.UltraWinSchedule.DayView.AppointmentUIElement elem = parent as Infragistics.Win.UltraWinSchedule.DayView.AppointmentUIElement; appt = elem.SelectableItem as Appointment; margin = new Size(8, 4); prevSibling = parent.GetDescendant(typeof(EditorWithTextUIElement)); } else if (parent is Infragistics.Win.UltraWinSchedule.MonthViewSingle.AppointmentUIElement) { Infragistics.Win.UltraWinSchedule.MonthViewSingle.AppointmentUIElement elem = parent as Infragistics.Win.UltraWinSchedule.MonthViewSingle.AppointmentUIElement; appt = elem.SelectableItem as Appointment; margin = new Size(8, 2); prevSibling = parent.GetDescendant(typeof(SingleDayAppointmentSubjectUIElement)); } else if (parent is Infragistics.Win.UltraWinSchedule.TimelineView.AppointmentUIElement) { Infragistics.Win.UltraWinSchedule.TimelineView.AppointmentUIElement elem = parent as Infragistics.Win.UltraWinSchedule.TimelineView.AppointmentUIElement; appt = elem.SelectableItem as Appointment; margin = new Size(8, 2); prevSibling = parent.GetDescendant(typeof(EditorWithTextUIElement)); } AddIconIfRequired(parent, appt, margin, prevSibling); } public bool BeforeCreateChildElements(UIElement parent) { return false; } #endregion #region Helpers void AddIconIfRequired(UIElement parent, Appointment appt, Size margin, UIElement prevSibling) { if (appt != null) { if (appt.RecurrenceId.CompareTo(FrmCalendar._recurrenceNoneGuid) != 0) { Image img = appt.RecurrenceId.CompareTo(FrmCalendar._recurrenceRootGuid) == 0 ? Properties.Resources.Recurring : Properties.Resources.RecurringEdit; ImageUIElement recurrenceIcon = new ImageUIElement(parent, img); Point ptIcon = new Point(Math.Max(parent.Rect.Right - img.Size.Width - margin.Width, 0), parent.Rect.Top + margin.Height); // resize the previous sibling element to accommodate the new icon if (prevSibling != null) { prevSibling.Rect = new Rectangle(prevSibling.Rect.Location, new Size(Math.Max(prevSibling.Rect.Width - img.Size.Width - margin.Width, 0), prevSibling.Rect.Height)); } recurrenceIcon.Rect = new System.Drawing.Rectangle(ptIcon, new Size(img.Size.Width, img.Size.Height)); parent.ChildElements.Add(recurrenceIcon); } } } #endregion }