/// <summary>
        /// Binds the campus grid.
        /// </summary>
        private void BindCampusGrid()
        {
            if (_eventItem != null)
            {
                pnlEventCalendarCampusItems.Visible = true;

                var rockContext = new RockContext();

                var qry = new EventItemOccurrenceService(rockContext)
                          .Queryable().AsNoTracking()
                          .Where(c => c.EventItemId == _eventItem.Id);

                // Filter by Campus
                List <int> campusIds = cblCampus.SelectedValuesAsInt;
                if (campusIds.Any())
                {
                    qry = qry
                          .Where(i =>
                                 !i.CampusId.HasValue ||
                                 campusIds.Contains(i.CampusId.Value));
                }

                SortProperty sortProperty = gCalendarItemOccurrenceList.SortProperty;

                // Sort and query db
                List <EventItemOccurrence> eventItemOccurrences = null;
                if (sortProperty != null)
                {
                    // If sorting on date, wait until after checking to see if date range was specified
                    if (sortProperty.Property == "Date")
                    {
                        eventItemOccurrences = qry.ToList();
                    }
                    else
                    {
                        eventItemOccurrences = qry.Sort(sortProperty).ToList();
                    }
                }
                else
                {
                    eventItemOccurrences = qry.ToList().OrderBy(a => a.NextStartDateTime).ToList();
                }

                // Contact filter
                if (!string.IsNullOrWhiteSpace(tbContact.Text))
                {
                    eventItemOccurrences = eventItemOccurrences
                                           .Where(i =>
                                                  i.ContactPersonAlias != null &&
                                                  i.ContactPersonAlias.Person != null &&
                                                  i.ContactPersonAlias.Person.FullName.Contains(tbContact.Text))
                                           .ToList();
                }

                // Now that items have been loaded and ordered from db, calculate the next start date for each item
                var eventItemOccurrencesWithDates = eventItemOccurrences
                                                    .Select(i => new EventItemOccurrenceWithDates
                {
                    EventItemOccurrence = i,
                    NextStartDateTime   = i.NextStartDateTime,
                })
                                                    .ToList();

                var dateCol = gCalendarItemOccurrenceList.Columns.OfType <BoundField>().Where(c => c.DataField == "Date").FirstOrDefault();

                // if a date range was specified, need to get all dates for items and filter based on any that have an occurrence withing the date range
                DateTime?lowerDateRange = drpDate.LowerValue;
                DateTime?upperDateRange = drpDate.UpperValue;
                if (lowerDateRange.HasValue || upperDateRange.HasValue)
                {
                    // If only one value was included, default the other to be a years difference
                    lowerDateRange = lowerDateRange ?? upperDateRange.Value.AddYears(-1).AddDays(1);
                    upperDateRange = upperDateRange ?? lowerDateRange.Value.AddYears(1).AddDays(-1);

                    // Get the start datetimes within the selected date range
                    eventItemOccurrencesWithDates.ForEach(i => i.StartDateTimes = i.EventItemOccurrence.GetStartTimes(lowerDateRange.Value, upperDateRange.Value.AddDays(1)));

                    // Filter out calendar items with no dates within range
                    eventItemOccurrencesWithDates = eventItemOccurrencesWithDates.Where(i => i.StartDateTimes.Any()).ToList();

                    // Update the Next Start Date to be the next date in range instead
                    dateCol.HeaderText = "Next Date In Range";
                    eventItemOccurrencesWithDates.ForEach(i => i.NextStartDateTime = i.StartDateTimes.Min());
                }
                else
                {
                    dateCol.HeaderText = "Next Start Date";
                }

                // Now sort on date if that is what was selected
                if (sortProperty != null && sortProperty.Property == "Date")
                {
                    if (sortProperty.Direction == SortDirection.Ascending)
                    {
                        eventItemOccurrencesWithDates = eventItemOccurrencesWithDates.OrderBy(a => a.NextStartDateTime).ToList();
                    }
                    else
                    {
                        eventItemOccurrencesWithDates = eventItemOccurrencesWithDates.OrderByDescending(a => a.NextStartDateTime).ToList();
                    }
                }

                gCalendarItemOccurrenceList.EntityTypeId = EntityTypeCache.Get <Rock.Model.EventItemOccurrence>().Id;
                gCalendarItemOccurrenceList.ObjectList   = new Dictionary <string, object>();
                eventItemOccurrencesWithDates.ForEach(i => gCalendarItemOccurrenceList.ObjectList.Add(i.EventItemOccurrence.Id.ToString(), i.EventItemOccurrence));
                gCalendarItemOccurrenceList.DataSource = eventItemOccurrencesWithDates
                                                         .Select(c => new
                {
                    c.EventItemOccurrence.Id,
                    c.EventItemOccurrence.Guid,
                    Campus   = c.EventItemOccurrence.Campus != null ? c.EventItemOccurrence.Campus.Name : "All Campuses",
                    Date     = c.NextStartDateTime.HasValue ? c.NextStartDateTime.Value.ToShortDateString() : "N/A",
                    Location = c.EventItemOccurrence.Location,
                    RegistrationInstanceId = c.EventItemOccurrence.Linkages.Any() ? c.EventItemOccurrence.Linkages.FirstOrDefault().RegistrationInstanceId : ( int? )null,
                    RegistrationInstance   = c.EventItemOccurrence.Linkages.Any() ? c.EventItemOccurrence.Linkages.FirstOrDefault().RegistrationInstance : null,
                    GroupId      = c.EventItemOccurrence.Linkages.Any() ? c.EventItemOccurrence.Linkages.FirstOrDefault().GroupId : ( int? )null,
                    Group        = c.EventItemOccurrence.Linkages.Any() ? c.EventItemOccurrence.Linkages.FirstOrDefault().Group : null,
                    ContentItems = FormatContentItems(c.EventItemOccurrence.ContentChannelItems.Select(i => i.ContentChannelItem).ToList()),
                    Contact      = c.EventItemOccurrence.ContactPersonAlias != null ? c.EventItemOccurrence.ContactPersonAlias.Person.FullName : "",
                    Phone        = c.EventItemOccurrence.ContactPhone,
                    Email        = c.EventItemOccurrence.ContactEmail,
                })
                                                         .ToList();
                gCalendarItemOccurrenceList.DataBind();
            }
            else
            {
                pnlEventCalendarCampusItems.Visible = false;
            }
        }
        /// <summary>
        /// Binds the campus grid.
        /// </summary>
        private void BindCampusGrid()
        {
            if ( _eventItem != null )
            {
                pnlEventCalendarCampusItems.Visible = true;

                var rockContext = new RockContext();

                var qry = new EventItemOccurrenceService( rockContext )
                    .Queryable().AsNoTracking()
                    .Where( c => c.EventItemId == _eventItem.Id );

                // Filter by Campus
                List<int> campusIds = cblCampus.SelectedValuesAsInt;
                if ( campusIds.Any() )
                {
                    qry = qry
                        .Where( i =>
                            !i.CampusId.HasValue ||
                            campusIds.Contains( i.CampusId.Value ) );
                }

                SortProperty sortProperty = gCalendarItemOccurrenceList.SortProperty;

                // Sort and query db
                List<EventItemOccurrence> eventItemOccurrences = null;
                if ( sortProperty != null )
                {
                    // If sorting on date, wait until after checking to see if date range was specified
                    if ( sortProperty.Property == "Date" )
                    {
                        eventItemOccurrences = qry.ToList();
                    }
                    else
                    {
                        eventItemOccurrences = qry.Sort( sortProperty ).ToList();
                    }
                }
                else
                {
                    eventItemOccurrences = qry.ToList().OrderBy( a => a.NextStartDateTime ).ToList();
                }

                // Contact filter
                if ( !string.IsNullOrWhiteSpace( tbContact.Text ) )
                {
                    eventItemOccurrences = eventItemOccurrences
                        .Where( i =>
                            i.ContactPersonAlias != null &&
                            i.ContactPersonAlias.Person != null &&
                            i.ContactPersonAlias.Person.FullName.Contains( tbContact.Text ) )
                        .ToList();
                }

                // Now that items have been loaded and ordered from db, calculate the next start date for each item
                var eventItemOccurrencesWithDates = eventItemOccurrences
                    .Select( i => new EventItemOccurrenceWithDates
                    {
                        EventItemOccurrence = i,
                        NextStartDateTime = i.NextStartDateTime,
                    } )
                    .ToList();

                var dateCol = gCalendarItemOccurrenceList.Columns.OfType<BoundField>().Where( c => c.DataField == "Date" ).FirstOrDefault();

                // if a date range was specified, need to get all dates for items and filter based on any that have an occurrence withing the date range
                DateTime? lowerDateRange = drpDate.LowerValue;
                DateTime? upperDateRange = drpDate.UpperValue;
                if ( lowerDateRange.HasValue || upperDateRange.HasValue )
                {
                    // If only one value was included, default the other to be a years difference
                    lowerDateRange = lowerDateRange ?? upperDateRange.Value.AddYears( -1 ).AddDays( 1 );
                    upperDateRange = upperDateRange ?? lowerDateRange.Value.AddYears( 1 ).AddDays( -1 );

                    // Get the start datetimes within the selected date range
                    eventItemOccurrencesWithDates.ForEach( i => i.StartDateTimes = i.EventItemOccurrence.GetStartTimes( lowerDateRange.Value, upperDateRange.Value.AddDays( 1 ) ) );

                    // Filter out calendar items with no dates within range
                    eventItemOccurrencesWithDates = eventItemOccurrencesWithDates.Where( i => i.StartDateTimes.Any() ).ToList();

                    // Update the Next Start Date to be the next date in range instead
                    dateCol.HeaderText = "Next Date In Range";
                    eventItemOccurrencesWithDates.ForEach( i => i.NextStartDateTime = i.StartDateTimes.Min() );
                }
                else
                {
                    dateCol.HeaderText = "Next Start Date";
                }

                // Now sort on date if that is what was selected
                if ( sortProperty != null && sortProperty.Property == "Date" )
                {
                    if ( sortProperty.Direction == SortDirection.Ascending )
                    {
                        eventItemOccurrencesWithDates = eventItemOccurrencesWithDates.OrderBy( a => a.NextStartDateTime ).ToList();
                    }
                    else
                    {
                        eventItemOccurrencesWithDates = eventItemOccurrencesWithDates.OrderByDescending( a => a.NextStartDateTime ).ToList();
                    }
                }

                gCalendarItemOccurrenceList.DataSource = eventItemOccurrencesWithDates
                    .Select( c => new
                    {
                        c.EventItemOccurrence.Id,
                        c.EventItemOccurrence.Guid,
                        Campus = c.EventItemOccurrence.Campus != null ? c.EventItemOccurrence.Campus.Name : "All Campuses",
                        Date = c.NextStartDateTime.HasValue ? c.NextStartDateTime.Value.ToShortDateString() : "N/A",
                        Location = c.EventItemOccurrence.Location,
                        RegistrationInstanceId = c.EventItemOccurrence.Linkages.Any() ? c.EventItemOccurrence.Linkages.FirstOrDefault().RegistrationInstanceId : (int?)null,
                        RegistrationInstance = c.EventItemOccurrence.Linkages.Any() ? c.EventItemOccurrence.Linkages.FirstOrDefault().RegistrationInstance : null,
                        GroupId = c.EventItemOccurrence.Linkages.Any() ? c.EventItemOccurrence.Linkages.FirstOrDefault().GroupId : (int?)null,
                        Group = c.EventItemOccurrence.Linkages.Any() ? c.EventItemOccurrence.Linkages.FirstOrDefault().Group : null,
                        ContentItems = FormatContentItems( c.EventItemOccurrence.ContentChannelItems.Select( i => i.ContentChannelItem ).ToList() ),
                        Contact = c.EventItemOccurrence.ContactPersonAlias != null ? c.EventItemOccurrence.ContactPersonAlias.Person.FullName : "",
                        Phone = c.EventItemOccurrence.ContactPhone,
                        Email = c.EventItemOccurrence.ContactEmail,
                    } )
                    .ToList();
                gCalendarItemOccurrenceList.DataBind();
            }
            else
            {
                pnlEventCalendarCampusItems.Visible = false;
            }
        }