I have a timelineview with a one day PrimaryInterval.
The main use is to mark holidays and sick leave. And that works great. But the problem is that shorter appointments (a couple of hours) become very narrow.
Is there a way to scale the drawing of these appointments based on the LogicalDayDuration on UltraCalanderInfo?
Hello,
What you could do in your case is to make the column wider (UltraTimelineView.ColumnWidth = 150), then the appointments will becomes wider.
Please let me know if you have any further questions.
This does not help what I'm trying to achieve, this way the number of days you can see at once is drastically reduced. In the application I need to see both longer appointments (spanning several days, even weeks) and short appointment(an hour or two).
When you have the PrimaryInterval as an hour and LogicalDayDuration is less than 24 hours, and LogicalDayOffset is larger than 0, then some part of the day is not shown.
What I would like to do is scale the drawing of the short appointments according to the LocigalDayDuration instead of 24 hours.
What I did was using a CreationFilter.
This is the code I used:
public void AfterCreateChildElements(UIElement parent)
{
Appointment appointment = null;
if (parent is Infragistics.Win.UltraWinSchedule.TimelineView.AppointmentUIElement)
var appUI = (Infragistics.Win.UltraWinSchedule.TimelineView.AppointmentUIElement)parent;
appointment = appUI.Appointment;
if (ultraTimelineView1.PrimaryInterval is DateInterval)
int dayWidth = ultraTimelineView1.ColumnWidthResolved - 5;
if (parent.Rect.Width < dayWidth)//less than a day.
Dictionary<DateTime, TimeSlotUIElement> timeslots = new Dictionary<DateTime, TimeSlotUIElement>();
foreach (var child in parent.Parent.ChildElements)
if (child is TimeSlotUIElement)
TimeSlotUIElement ts = (TimeSlotUIElement)child;
if (!timeslots.ContainsKey(ts.DateTimeRange.StartDateTime))
timeslots.Add(ts.DateTimeRange.StartDateTime, ts);
}
double workingHoursCalc = 8.00;
double startDay = 8.00;// in hours
startDay = ultraCalendarInfo1.LogicalDayOffset.TotalHours;
workingHours = ultraCalendarInfo1.LogicalDayDuration.TotalHours;
double forhold = appointment.EndDateTime.Subtract(appointment.StartDateTime).TotalHours / workingHoursCalc;
if (timeslots.ContainsKey(appointment.StartDateTime.Date))
var ts = timeslots[appointment.StartDateTime.Date];
int newStart = ts.RectInsideBorders.X;
double pixelPrHour = ts.RectInsideBorders.Width / workingHoursCalc;
int newOffset = (int)((appointment.StartDateTime.TimeOfDay.TotalHours - startDay) * pixelPrHour);
if (newOffset < 0)
newOffset = 0;
int newX = newStart + newOffset;
int newWidth = (int)(appointment.EndDateTime.Subtract(appointment.StartDateTime).TotalHours * pixelPrHour);
int newWidth2 = (int)(ts.RectInsideBorders.Width * forhold);
if (newWidth > ts.RectInsideBorders.Width)
newWidth = ts.RectInsideBorders.Width;
else if (newX + newWidth > ts.RectInsideBorders.X + ts.RectInsideBorders.Width)
newX = ts.RectInsideBorders.X + ts.RectInsideBorders.Width - newWidth;
parent.Rect = new Rectangle(newX, parent.Rect.Y, newWidth, parent.Rect.Height);
Any suggestions as to making it more efficient would be welcome.
Hello ,
I have reviewed and modified your code a little in order to make it more efficient:
#region
IUIElementCreationFilter Members
static Dictionary<DateTime, TimeSlotUIElement> timeslots = new Dictionary<DateTime, TimeSlotUIElement>();
static double workingHoursCalc = 8.00;
static double startDay = 8.00;// in hours
if (parent is ActivityAreaUIElement)
timeslots.Clear();
parent.ChildElements.Where(UI => UI
is TimeSlotUIElement).ToList<UIElement>().ForEach(
delegate(UIElement ts)
if (!timeslots.ContainsKey(((TimeSlotUIElement)ts).DateTimeRange.StartDateTime))
timeslots.Add(((
TimeSlotUIElement)ts).DateTimeRange.StartDateTime, ((TimeSlotUIElement)ts));
});
if (parent is Infragistics.Win.UltraWinSchedule.TimelineView.AppointmentUIElement && ultraTimelineView1.PrimaryInterval is DateInterval)
appointment = ((Infragistics.Win.UltraWinSchedule.TimelineView.
AppointmentUIElement)parent).Appointment;
double workingHours = ultraCalendarInfo1.LogicalDayDuration.TotalHours;
int newOffset = Math.Max((int)((appointment.StartDateTime.TimeOfDay.TotalHours - startDay) * pixelPrHour), 0);
int newWidth = (int)(appointment.Span.TotalHours * pixelPrHour);
parent.Rect =
new Rectangle(newX, parent.Rect.Y, newWidth, parent.Rect.Height);
public bool BeforeCreateChildElements(UIElement parent)
return false;
#endregion
Hello,
I am just checking about the progress of this issue. Let me know If you need my further assistance on this issue?
Thank you for using Infragistics Components.
I have made some test with my code and with your code. I assume that UltraCalendarInfo has 10 appointments. And when I run the application (there is no user actions only run the application). CreationFilter creates once ActivityAreaUIElement so I have only one loop trough child elements of ActivityAreaUIElement. Also I have made the same test with your code and AppointmentUIElements are created for all visible appointment (in my case loop trough child elements of ActivityAreaUIElement was 20 times, because when you modified UIElement this causing faring of AfterCreateChildElements method again). Please run the attached sample and see the output. Please comment my code (uncomment yours) , run the application again and see the output.
Maybe in your specific scenario, your code is better than my, so please test both code in more specific scenario and evaluate which will be more efficient for you.
Please let me know if you have any further questions or if I am missing something.
I disagree that your code is more efficient (at least with the data that I intend to use).
Your code loops through the ChildElements of ActivityAreaUIElement everytime it is drawn. This happens everytime the user changes the range of dates shown or the owner that is in view.
My code on the other hand, only loops through the ChildElements when an appointment that is shorter than a day is created (ie comes into view).
In my use case the majority of appointments lasts for more than a day.