A class that represents the time area that build the timer ruler part of the day view.
Inheritance: Telerik.UI.Xaml.Controls.Input.Calendar.CalendarNode
        private void EnsureTimeRulerItems()
        {
            if (this.timeRulerItems == null)
            {
                this.timeRulerItems = new ElementCollection <CalendarTimeRulerItem>(this);
            }

            if (this.timeRulerItems.Count == 0)
            {
                MultiDayViewSettings settings = this.Calendar.multiDayViewSettings;

                long   dayViewAreaTicks = settings.DayEndTime.Ticks - settings.DayStartTime.Ticks;
                double numberOfItems    = Math.Ceiling((double)dayViewAreaTicks / (double)settings.TimerRulerTickLength.Ticks);
                for (int i = 0; i < numberOfItems; i++)
                {
                    CalendarTimeRulerItem timeRulerItem = new CalendarTimeRulerItem();
                    this.timeRulerItems.Add(timeRulerItem);
                }
            }
            else
            {
                foreach (CalendarTimeRulerItem timeRulerItem in this.timeRulerItems)
                {
                    timeRulerItem.layoutSlot = RadRect.Empty;
                }
            }
        }
        private static TimeSpan GetExactTimeFromPoint(Point hitPoint, CalendarTimeRulerItem item, double halfTextHeight, double lineThickness)
        {
            var layoutSlot  = item.layoutSlot;
            var layoutSlotY = layoutSlot.Y + halfTextHeight - lineThickness / 2;

            var      yDiff = hitPoint.Y - layoutSlotY;
            var      coeff = yDiff / layoutSlot.Height;
            TimeSpan totalSlotTimeLenght   = item.EndTime - item.StartTime;
            var      exactTimeMilliseconds = totalSlotTimeLenght.TotalMilliseconds * coeff;
            var      exactTime             = TimeSpan.FromMilliseconds(exactTimeMilliseconds);

            return(item.StartTime.Add(exactTime));
        }
        private void ArrangeTimerRuler(RadRect viewRect)
        {
            CalendarModel        model       = this.Calendar;
            MultiDayViewSettings settings    = model.multiDayViewSettings;
            DateTime             currentDate = model.DisplayDate.Date;

            double   timeWidth     = this.dayViewLayoutSlot.X - viewRect.X;
            TimeSpan timeSlotTime  = settings.DayStartTime;
            string   textToMeasure = string.Format(this.Calendar.Culture, this.Calendar.TimeFormat, currentDate.Add(timeSlotTime));
            RadSize  timeTextSize  = model.View.MeasureContent(null, textToMeasure);

            this.halfTextHeight = timeTextSize.Height / 2;

            double previousBottom = viewRect.Y - this.halfTextHeight;

            string labelText = string.Empty;
            double heightCoeff;
            double timeItemHeight;
            double oneHourTicks = (double)TimeSpan.FromHours(1).Ticks;

            var itemsCount = this.timeRulerItems.Count;

            for (int hourIndex = 0; hourIndex < itemsCount; hourIndex++)
            {
                CalendarTimeRulerItem timerRulerItem = this.timeRulerItems[hourIndex];
                timerRulerItem.StartTime = timeSlotTime;
                timerRulerItem.Label     = labelText;

                timeSlotTime = timeSlotTime.Add(TimeSpan.FromTicks(settings.TimerRulerTickLength.Ticks));
                if (timeSlotTime > settings.DayEndTime)
                {
                    timeSlotTime = settings.DayEndTime;
                }

                timerRulerItem.EndTime = timeSlotTime;

                heightCoeff    = (timerRulerItem.EndTime - timerRulerItem.StartTime).Ticks / oneHourTicks;
                timeItemHeight = settings.TimeLinesSpacing * heightCoeff;
                if (hourIndex == itemsCount - 1)
                {
                    timeItemHeight += this.halfTextHeight - this.Calendar.GridLinesThickness;
                }

                timerRulerItem.Arrange(new RadRect(0f, previousBottom, timeWidth, timeItemHeight));

                previousBottom = timerRulerItem.layoutSlot.Bottom;
                labelText      = string.Format(this.Calendar.Culture, this.Calendar.TimeFormat, currentDate.Add(timeSlotTime));
            }
        }
        private double DateToVerticalPosition(DateTime currentDate, DateTime dateToMeasure)
        {
            CalendarTimeRulerItem currentTimRulerItem = null;
            TimeSpan timeOfDay;
            double   verticalPosition = this.halfTextHeight - this.Calendar.GridLinesThickness / 2;

            if (currentDate.Date.Date < dateToMeasure.Date)
            {
                currentTimRulerItem = this.timeRulerItems.Last();
                timeOfDay           = currentTimRulerItem.EndTime;
            }
            else if (currentDate.Date.Date > dateToMeasure.Date)
            {
                currentTimRulerItem = this.timeRulerItems.First();
                timeOfDay           = currentTimRulerItem.StartTime;
            }
            else
            {
                timeOfDay           = dateToMeasure.TimeOfDay;
                currentTimRulerItem = this.timeRulerItems.FirstOrDefault(a => a.StartTime <= timeOfDay && a.EndTime >= timeOfDay);
            }

            if (currentTimRulerItem != null)
            {
                verticalPosition += currentTimRulerItem.layoutSlot.Y;

                TimeSpan totalSlotTimeLenght = currentTimRulerItem.EndTime - currentTimRulerItem.StartTime;
                TimeSpan timeDifference      = totalSlotTimeLenght - (currentTimRulerItem.EndTime - timeOfDay);

                double positionCoeff = timeDifference.TotalMilliseconds / totalSlotTimeLenght.TotalMilliseconds;
                if (positionCoeff > 0)
                {
                    double heightCoeff = (double)this.Calendar.multiDayViewSettings.TimerRulerTickLength.Ticks
                                         / (double)TimeSpan.FromHours(1).Ticks;
                    double timeItemHeight = this.Calendar.multiDayViewSettings.TimeLinesSpacing * heightCoeff;

                    double slotPositionDifference = timeItemHeight * positionCoeff;
                    verticalPosition += slotPositionDifference;
                }
            }
            else
            {
                verticalPosition = 0;
            }

            return(verticalPosition);
        }
        private FrameworkElement GetDefaultTimeRulerItemVisual(CalendarTimeRulerItem timeRulerItem)
        {
            TextBlock visual;

            if (this.recycledTimeRulerItems.Count > 0)
            {
                visual = this.recycledTimeRulerItems.Dequeue();

                visual.ClearValue(TextBlock.VisibilityProperty);
                visual.ClearValue(TextBlock.StyleProperty);
            }
            else
            {
                visual = this.CreateDefaultTimeRulerItemVisual();
            }

            visual.Text = timeRulerItem.Label;

            this.realizedTimerRulerItemsPresenters.Add(timeRulerItem, visual);
            return(visual);
        }