internal void ScrollAppointmentIntoView(IAppointment appointment)
        {
            RadCalendar calendar = this.Owner;

            if (calendar != null)
            {
                CalendarMultiDayViewModel model = calendar.Model.multiDayViewModel;
                var appointmentInfos            = model.appointmentInfos;
                if (appointmentInfos != null && appointmentInfos.Count > 0)
                {
                    DateTime startDate = calendar.DisplayDate;
                    DateTime endDate   = calendar.DisplayDate.AddDays(calendar.MultiDayViewSettings.VisibleDays - 1);
                    CalendarAppointmentInfo appointmentInfo = appointmentInfos.FirstOrDefault(a => a.childAppointment == appointment && startDate <= a.Date && endDate >= a.Date);
                    if (appointmentInfo != null)
                    {
                        RadRect layoutSlot = appointmentInfo.layoutSlot;
                        if (this.scrollViewer.VerticalOffset != layoutSlot.Y)
                        {
                            this.isScrollingInvoked = true;
                            this.scrollViewer.ChangeView(0.0f, layoutSlot.Y, 1.0f);
                        }
                    }
                }
            }
        }
        private void SetColumnsOfIntersectedAppointments(IEnumerable <CalendarAppointmentInfo> intersectedAppointments, CalendarAppointmentInfo parentAppointmentInfo, int columnIndex)
        {
            for (int i = 0; i < intersectedAppointments.Count(); i++)
            {
                CalendarAppointmentInfo app = intersectedAppointments.ElementAt(i);
                if (app == parentAppointmentInfo)
                {
                    int index = columnIndex;
                    while (intersectedAppointments.Any(a => a.arrangeColumnIndex == index))
                    {
                        index++;
                    }

                    app.arrangeColumnIndex = index;
                    continue;
                }

                if (app.arrangeColumnIndex == null)
                {
                    IEnumerable <CalendarAppointmentInfo> childIntersectedAppointments = intersectedAppointments
                                                                                         .Where(a => a.layoutSlot.IntersectsWith(app.layoutSlot) && a.columnIndex == app.columnIndex);

                    this.SetColumnsOfIntersectedAppointments(childIntersectedAppointments, app, columnIndex + 1);
                }
            }
        }
        /// <summary>
        /// Evaluates the appearance settings to be applied on the respective calendar appointment control.
        /// </summary>
        /// <param name="context">The CalendarAppointmentInfo context.</param>
        /// <param name="cell">The CalendarCellModel cell.</param>
        public DataTemplate SelectTemplate(CalendarAppointmentInfo context, CalendarCellModel cell)
        {
            if (cell == null)
            {
                return(null);
            }

            return(this.SelectTemplateCore(context, cell));
        }
        internal void UpdateUI(IEnumerable <CalendarCellModel> cellsToUpdate = null)
        {
            if (this.Owner.AppointmentSource == null)
            {
                return;
            }
            if (cellsToUpdate == null)
            {
                cellsToUpdate = this.Owner.Model.CalendarCells;
            }

            int         index    = 0;
            RadCalendar calendar = this.Owner;

            foreach (CalendarCellModel cell in cellsToUpdate)
            {
                CalendarAppointmentInfo info = new CalendarAppointmentInfo();
                info.Date         = cell.Date;
                info.Appointments = this.Owner.AppointmentSource.GetAppointments((IAppointment appointment) =>
                {
                    return(cell.Date.Date >= appointment.StartDate.Date && cell.Date.Date <= appointment.EndDate.Date);
                });

                if (info.Appointments.Count > 0)
                {
                    foreach (var appointment in info.Appointments)
                    {
                        info.Subject += (info.Subject != null ? Environment.NewLine : string.Empty) + appointment.Subject;
                    }

                    var element = this.GetDefaultVisual(index);
                    element.Clip = new RectangleGeometry()
                    {
                        Rect = new Rect(0, 0, cell.LayoutSlot.Width, cell.LayoutSlot.Height)
                    };
                    element.appointmentInfo = info;
                    calendar.PrepareContainerForAppointment(element, info);

                    RadRect layoutSlot = cell.layoutSlot;
                    layoutSlot = XamlContentLayerHelper.ApplyLayoutSlotAlignment(element, layoutSlot);
                    XamlContentLayer.ArrangeUIElement(element, layoutSlot, false);
                    index++;
                }
            }

            while (index < this.realizedCalendarCellDefaultPresenters.Count)
            {
                this.realizedCalendarCellDefaultPresenters[index].Visibility = Visibility.Collapsed;
                index++;
            }
        }
        private void ArrangeIntersectedAppointments()
        {
            double gridLineThickness = this.Calendar.GridLinesThickness > 0 ? this.Calendar.GridLinesThickness : 1;

            foreach (var appointmentInfo in this.appointmentInfos)
            {
                if (!appointmentInfo.isArranged)
                {
                    List <CalendarAppointmentInfo> intersectedAppointments = this.appointmentInfos.Where(a => a.layoutSlot.IntersectsWith(appointmentInfo.layoutSlot) && a.columnIndex == appointmentInfo.columnIndex).ToList();
                    int intersectedAppointmentsCount = intersectedAppointments.Count;
                    if (intersectedAppointmentsCount > 1)
                    {
                        this.SetColumnsOfIntersectedAppointments(intersectedAppointments, appointmentInfo, 0);
                        int    columnsCount = intersectedAppointments.Max(a => a.arrangeColumnIndex.Value) + 1;
                        var    orderedIntersectedAppointments = intersectedAppointments.OrderBy(a => a.arrangeColumnIndex).ToList();
                        double maxWidth = appointmentInfo.layoutSlot.Width / columnsCount;
                        for (int i = 0; i < intersectedAppointmentsCount; i++)
                        {
                            CalendarAppointmentInfo intersectedAppointment = orderedIntersectedAppointments[i];
                            if (!intersectedAppointment.isArranged)
                            {
                                RadRect layout = intersectedAppointment.layoutSlot;
                                layout.X     = layout.X + (maxWidth * intersectedAppointment.arrangeColumnIndex.Value);
                                layout.Width = maxWidth;

                                intersectedAppointment.layoutSlot = layout;
                                intersectedAppointment.isArranged = true;
                            }
                            else
                            {
                                RadRect layout = intersectedAppointment.layoutSlot;
                                if (layout.Width > maxWidth)
                                {
                                    this.OffsetChildIntersectedAppointments(intersectedAppointment, maxWidth);
                                }
                            }
                        }
                    }
                }
            }
        }
        private void OffsetChildIntersectedAppointments(CalendarAppointmentInfo intersectedAppointment, double maxWidth)
        {
            var childIntersectedAppointments = this.appointmentInfos.Where(a => a.layoutSlot.IntersectsWith(intersectedAppointment.layoutSlot) &&
                                                                           a.columnIndex == intersectedAppointment.columnIndex).ToList();

            RadRect layout = intersectedAppointment.layoutSlot;

            double offset = (layout.Width - maxWidth) * intersectedAppointment.arrangeColumnIndex.Value;

            layout.X    -= offset;
            layout.Width = maxWidth;
            intersectedAppointment.layoutSlot = layout;

            foreach (CalendarAppointmentInfo app in childIntersectedAppointments)
            {
                if (app.isArranged && app.layoutSlot.Width > maxWidth)
                {
                    this.OffsetChildIntersectedAppointments(app, maxWidth);
                }
            }
        }
示例#7
0
        private AppointmentControl GetDefaultAllDayAppointmentVisual(CalendarAppointmentInfo info)
        {
            AppointmentControl visual;

            if (this.recycledAppointments.Count > 0)
            {
                visual = this.recycledAppointments.Dequeue();
            }
            else if (this.fullyRecycledAppointments.Count > 0)
            {
                visual = this.fullyRecycledAppointments.Dequeue();
                visual.ClearValue(AppointmentControl.VisibilityProperty);
            }
            else
            {
                visual = this.CreateDefaultAllDayAppointmentVisual();
            }

            this.realizedAppointmentPresenters.Add(info, visual);
            return(visual);
        }
        private void ArrangeAllDayAppointment(RadRect viewRect)
        {
            AppointmentSource appointmentSource = this.Calendar.appointmentSource;

            if (this.allDayAppointmentInfos == null)
            {
                this.allDayAppointmentInfos = new List <CalendarAppointmentInfo>();
            }
            else
            {
                this.allDayAppointmentInfos.Clear();
            }

            if (appointmentSource != null)
            {
                MultiDayViewSettings settings = this.Calendar.multiDayViewSettings;
                double appoitmentHeight       = settings.AllDayAppointmentMinHeight;

                foreach (var cell in this.CalendarCells)
                {
                    LinkedList <IAppointment> appointments = appointmentSource.GetAppointments((IAppointment appointment) =>
                    {
                        return(cell.Date.Date >= appointment.StartDate.Date && cell.Date.Date <= appointment.EndDate.Date && appointment.IsAllDay);
                    });

                    if (appointments.Count > this.allDayAreaRowCount)
                    {
                        this.allDayAreaRowCount = appointments.Count;
                    }

                    var    sorterAppointments = appointments.OrderByDescending(a => a.EndDate.Ticks - a.StartDate.Ticks).ToList();
                    var    containedInfos     = this.allDayAppointmentInfos.Where(a => sorterAppointments.Contains(a.childAppointment));
                    double prevBottom         = cell.layoutSlot.Y - this.dayViewLayoutSlot.Y;

                    foreach (var appointment in sorterAppointments)
                    {
                        while (true)
                        {
                            int      widthCoeff;
                            int      xCoeff;
                            DateTime startAppointmentDate = appointment.StartDate;
                            if (this.Calendar.multiDayViewSettings.WeekendsVisible)
                            {
                                widthCoeff = (appointment.EndDate - startAppointmentDate).Days;
                                xCoeff     = (cell.Date - startAppointmentDate.Date).Days;
                            }
                            else
                            {
                                widthCoeff           = CalendarMathHelper.GetBusinessDaysCount(startAppointmentDate, appointment.EndDate);
                                startAppointmentDate = CalendarMathHelper.SetFirstAvailableBusinessDay(startAppointmentDate, 1);
                                xCoeff = CalendarMathHelper.GetBusinessDaysCount(startAppointmentDate.Date, cell.Date);
                            }

                            RadRect layoutSlot = new RadRect(cell.layoutSlot.X - (xCoeff * this.cellWidth), prevBottom, this.cellWidth + (this.cellWidth * widthCoeff) - this.Calendar.GridLinesThickness / 2, appoitmentHeight);
                            if (containedInfos.FirstOrDefault(a => a.layoutSlot.IntersectsWith(layoutSlot)) == null)
                            {
                                CalendarAppointmentInfo containedInfo = containedInfos.FirstOrDefault(a => a.childAppointment == appointment);
                                if (containedInfo != null)
                                {
                                    break;
                                }

                                CalendarAppointmentInfo info = new CalendarAppointmentInfo();
                                info.Date             = cell.Date;
                                info.Appointments     = appointments;
                                info.columnIndex      = cell.ColumnIndex;
                                info.Brush            = appointment.Color;
                                info.cell             = cell;
                                info.childAppointment = appointment;
                                info.DetailText       = appointment.Description;
                                info.Subject          = appointment.Subject;
                                info.IsAllDay         = appointment.IsAllDay;

                                info.layoutSlot = layoutSlot;
                                this.allDayAppointmentInfos.Add(info);
                                prevBottom = layoutSlot.Bottom + settings.AllDayAppointmentSpacing;
                                break;
                            }

                            prevBottom = layoutSlot.Bottom + settings.AllDayAppointmentSpacing;
                        }
                    }
                }

                int maxVisibleRows = settings.AllDayMaxVisibleRows;
                this.totalAllDayAreaHeight = this.allDayAreaRowCount > maxVisibleRows
                    ? maxVisibleRows * appoitmentHeight + maxVisibleRows * settings.AllDayAppointmentSpacing + appoitmentHeight / 2
                    : this.allDayAreaRowCount * appoitmentHeight + this.allDayAreaRowCount * settings.AllDayAppointmentSpacing;

                if (this.allDayAreaRowCount == 0)
                {
                    this.totalAllDayAreaHeight = 0;
                }
            }
        }
        internal void ArrangeAppointments()
        {
            AppointmentSource appointmentSource = this.Calendar.appointmentSource;

            if (this.appointmentInfos == null)
            {
                this.appointmentInfos = new List <CalendarAppointmentInfo>();
            }
            else
            {
                this.appointmentInfos.Clear();
            }

            if (appointmentSource != null)
            {
                MultiDayViewSettings settings = this.Calendar.multiDayViewSettings;
                foreach (var calendarCell in this.CalendarCells)
                {
                    LinkedList <IAppointment> appointmentsPerCell = appointmentSource.GetAppointments((IAppointment appointment) =>
                    {
                        return(calendarCell.Date.Date >= appointment.StartDate.Date &&
                               calendarCell.Date.Date <= appointment.EndDate.Date && !(appointment.IsAllDay && settings.ShowAllDayArea));
                    });

                    var orderedAppointments = new LinkedList <IAppointment>(appointmentsPerCell.OrderBy(a => a.StartDate));
                    foreach (var appointment in orderedAppointments)
                    {
                        if ((appointment.StartDate.Date == calendarCell.Date.Date && appointment.StartDate.TimeOfDay > settings.DayEndTime) ||
                            (appointment.EndDate.Date == calendarCell.Date.Date && appointment.EndDate.TimeOfDay < settings.DayStartTime))
                        {
                            continue;
                        }

                        double   startY  = this.DateToVerticalPosition(calendarCell.Date.Date, appointment.StartDate);
                        DateTime endDate = appointment.EndDate.TimeOfDay > settings.DayEndTime
                            ? appointment.EndDate.Add(TimeSpan.FromTicks(settings.DayEndTime.Ticks - appointment.EndDate.TimeOfDay.Ticks))
                            : appointment.EndDate;

                        double endY = this.DateToVerticalPosition(calendarCell.Date.Date, endDate);
                        if (startY < endY)
                        {
                            CalendarAppointmentInfo info = new CalendarAppointmentInfo();
                            info.Date             = calendarCell.Date;
                            info.Appointments     = orderedAppointments;
                            info.columnIndex      = calendarCell.ColumnIndex;
                            info.Brush            = appointment.Color;
                            info.cell             = calendarCell;
                            info.childAppointment = appointment;
                            info.DetailText       = appointment.Description;
                            info.Subject          = appointment.Subject;
                            info.IsAllDay         = appointment.IsAllDay;

                            DateTime currentAppointmentStartDate = appointment.StartDate;
                            DateTime currentAppointmentEndDate   = appointment.EndDate;
                            if (!this.Calendar.multiDayViewSettings.WeekendsVisible)
                            {
                                currentAppointmentStartDate = CalendarMathHelper.SetFirstAvailableBusinessDay(currentAppointmentStartDate, 1);
                                currentAppointmentEndDate   = CalendarMathHelper.SetFirstAvailableBusinessDay(currentAppointmentEndDate, -1);
                            }

                            info.hasPreviousDay = currentAppointmentStartDate.Date < calendarCell.Date;
                            info.hasNextDay     = currentAppointmentEndDate.Date > calendarCell.Date;
                            int     xCoeff     = (calendarCell.Date - appointment.StartDate.Date).Days;
                            RadRect layoutSlot = new RadRect(calendarCell.layoutSlot.X - this.timeRulerWidth, startY, calendarCell.layoutSlot.Width, endY - startY);
                            info.layoutSlot = layoutSlot;
                            this.appointmentInfos.Add(info);
                        }
                    }
                }

                this.ArrangeIntersectedAppointments();
            }
        }
        internal void UpdateUI(IEnumerable <CalendarCellModel> cellsToUpdate = null)
        {
            if (this.Owner.AppointmentSource == null)
            {
                return;
            }
            if (cellsToUpdate == null)
            {
                cellsToUpdate = this.Owner.Model.CalendarCells;
            }

            int         index    = 0;
            RadCalendar calendar = this.Owner;

            foreach (CalendarCellModel cell in cellsToUpdate)
            {
                CalendarAppointmentInfo info = new CalendarAppointmentInfo();
                info.Date         = cell.Date;
                info.Appointments = this.Owner.AppointmentSource.GetAppointments((IAppointment appointment) =>
                {
                    return(cell.Date.Date >= appointment.StartDate.Date && cell.Date.Date <= appointment.EndDate.Date);
                });

                if (info.Appointments.Count > 0)
                {
                    AppointmentControl element = new AppointmentControl();

                    foreach (var appointment in info.Appointments)
                    {
                        info.Subject += (info.Subject != null ? Environment.NewLine : string.Empty) + appointment.Subject;
                    }

                    element      = this.GetDefaultVisual(index);
                    element.Clip = new RectangleGeometry()
                    {
                        Rect = new Rect(0, 0, cell.LayoutSlot.Width, cell.LayoutSlot.Height)
                    };
                    element.Header          = info.Subject;
                    element.Background      = info.Brush;
                    element.appointmentInfo = info;

                    XamlContentLayerHelper.MeasureVisual(element);
                    if (element != null)
                    {
                        StyleSelector styleSelector = calendar.AppointmentStyleSelector;
                        if (styleSelector != null)
                        {
                            var style = styleSelector.SelectStyle(info, element);
                            if (style != null)
                            {
                                element.Style = style;
                            }
                        }

                        AppointmentTemplateSelector headerTemplateSelector = calendar.AppointmentHeaderTemplateSelector;
                        if (headerTemplateSelector != null)
                        {
                            DataTemplate template = headerTemplateSelector.SelectTemplate(info, info.cell);
                            if (template != null)
                            {
                                element.HeaderTemplate = template;
                            }
                        }

                        RadRect layoutSlot = cell.layoutSlot;
                        layoutSlot = XamlContentLayerHelper.ApplyLayoutSlotAlignment(element, layoutSlot);
                        XamlContentLayer.ArrangeUIElement(element, layoutSlot, false);

                        index++;
                    }
                }
            }

            while (index < this.realizedCalendarCellDefaultPresenters.Count)
            {
                this.realizedCalendarCellDefaultPresenters[index].Visibility = Visibility.Collapsed;
                index++;
            }
        }
示例#11
0
 private void RecycleAppointmentVisual(CalendarAppointmentInfo appointmentInfo, AppointmentControl visual)
 {
     this.realizedAppointmentPresenters.Remove(appointmentInfo);
     this.recycledAppointments.Enqueue(visual);
 }
 /// <summary>
 /// When implemented by a derived class, provides a way to tap into the default calendar appointment control appearance logic through the passed
 /// <see cref="CalendarAppointmentInfo" /> argument instance.
 /// </summary>
 /// <param name="context">The CalendarAppointmentInfo context.</param>
 /// <param name="cell">The CalendarCellModel cell.</param>
 protected abstract DataTemplate SelectTemplateCore(CalendarAppointmentInfo context, CalendarCellModel cell);